package freenet.client.async;
import java.io.IOException;
import freenet.client.ClientMetadata;
import freenet.client.FetchException;
import freenet.client.InsertContext.CompatibilityMode;
import freenet.crypt.ChecksumFailedException;
import freenet.keys.CHKBlock;
import freenet.keys.ClientCHKBlock;
import freenet.node.BaseSendableGet;
import freenet.support.api.Bucket;
/** Callback used by SplitFileFetcherStorage. Arguably this is over-abstraction purely to make unit
* tests easier without having to use Mockito (which presumably means solving the issues with
* Maven). OTOH maybe it has some other use ... FIXME reconsider.
* @author toad
*/
public interface SplitFileFetcherStorageCallback {
/** Called when the splitfile has been successfully downloaded and decoded. E.g.
* streamGenerator() should work now. However the splitfile storage layer may still need the
* data to e.g. encode healing blocks, so it cannot be freed until close(). The higher level
* code (e.g. SplitFileFetcher) must call finishedFetcher() when finished, and when that
* has been called *and* the storage layer has finished, it will close and free the underlying
* storage and call close() here. */
void onSuccess();
/** Get the priority class of the request. Needed for e.g. FEC decoding scheduling. */
short getPriorityClass();
/** Called when the splitfile storage layer receives an unrecoverable disk I/O error. */
void failOnDiskError(IOException e);
/** Called when the splitfile storage layer receives unrecoverable data corruption. */
void failOnDiskError(ChecksumFailedException e);
/** Called during construction to tell other layers how many blocks to expect.
* @param requiredBlocks The number of blocks that must be fetched to complete the download.
* @param remainingBlocks The total number of blocks minus requiredBlocks.
*/
void setSplitfileBlocks(int requiredBlocks, int remainingBlocks);
/**
* Called during construction, when we know the settings for the splitfile.
* @param min The lowest CompatibilityMode that appears to be valid based on what we've fetched so far.
* @param max The highest CompatibilityMode that appears to be valid based on what we've fetched so far.
* @param customSplitfileKey The fixed byte[] encryption key used on insert. On anything recent, we generate a single key, randomly for an SSK,
* or based on the content for a CHK, and use it for everything. This saves metadata space and improves security for SSKs.
* @param compressed Whether the content is compressed. If false, the dontCompress option was used.
* @param bottomLayer Whether this report originates at the bottom layer of the splitfile pyramid. I.e. the actual file, not the file containing
* the metadata to fetch the file (this can recurse for several levels!)
* @param definitiveAnyway Whether this report is definitive even though it's not from the bottom layer. This is true of recent splitfiles,
* where we store all the data in the top key.
*/
void onSplitfileCompatibilityMode(CompatibilityMode min, CompatibilityMode max, byte[] customSplitfileKey, boolean compressed, boolean bottomLayer, boolean definitiveAnyway);
/** Queue a block to be healed. LOCKING: Called on the decode thread, so should avoid taking
* any dangerous locks and not be too slow. */
void queueHeal(byte[] data, byte[] cryptoKey, byte cryptoAlgorithm);
/** Called when the storage layer has finished, the higher level code has finished, and the
* storage has been freed, i.e. the request is now completely finished. */
void onClosed();
void onFetchedBlock();
/** Called when the splitfile fetcher gives up on a block. (Assumed to be a non-fatal error,
* run out of retries) */
void onFailedBlock();
void onResume(int succeededBlocks, int failedBlocks, ClientMetadata mimeType, long finalSize);
/** Called when the fetch failed, e.g. due to running out of retries. */
void fail(FetchException fetchException);
/** Called whenever we successfully download, decode or encode a block and it matches the
* expected key. LOCKING: Called on the decode thread so should avoid taking any dangerous
* locks. */
void maybeAddToBinaryBlob(ClientCHKBlock decodedBlock);
/** Do we want maybeAddToBinaryBlob() to be called?? LOCKING: Should not take any locks. */
boolean wantBinaryBlob();
/** Can be null. Provided mainly for KeysFetchingLocally. */
BaseSendableGet getSendableGet();
/** Called when we recover from disk corruption, and have to re-download some blocks that we
* had already downloaded but which were corrupted on disk. E.g. when a segment attempts to
* decode but discovers that a block doesn't match the key given. */
void restartedAfterDataCorruption();
/** Called when the fetcher may have exited cooldown early. */
void clearCooldown();
/** Called when the wakeup time reduces but it is still not fetchable. */
void reduceCooldown(long wakeupTime);
/** Can be null. Provided for KeyListeners. */
HasKeyListener getHasKeyListener();
KeySalter getSalter();
}