/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app.backup;

import android.compat.annotation.UnsupportedAppUsage;
import android.os.ParcelFileDescriptor;
import android.util.Log;

import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

/** @hide */
public class BackupHelperDispatcher {
    private static final String TAG = "BackupHelperDispatcher";

    private static class Header {
        @UnsupportedAppUsage
        int chunkSize; // not including the header
        @UnsupportedAppUsage
        String keyPrefix;
    }

    TreeMap<String,BackupHelper> mHelpers = new TreeMap<String,BackupHelper>();
    
    public BackupHelperDispatcher() {
    }

    public void addHelper(String keyPrefix, BackupHelper helper) {
        mHelpers.put(keyPrefix, helper);
    }

    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) throws IOException {
        // First, do the helpers that we've already done, since they're already in the state
        // file.
        int err;
        Header header = new Header();
        TreeMap<String,BackupHelper> helpers = (TreeMap<String,BackupHelper>)mHelpers.clone();
        FileDescriptor oldStateFD = null;

        if (oldState != null) {
            oldStateFD = oldState.getFileDescriptor();
            while ((err = readHeader_native(header, oldStateFD)) >= 0) {
                if (err == 0) {
                    BackupHelper helper = helpers.get(header.keyPrefix);
                    Log.d(TAG, "handling existing helper '" + header.keyPrefix + "' " + helper);
                    if (helper != null) {
                        doOneBackup(oldState, data, newState, header, helper);
                        helpers.remove(header.keyPrefix);
                    } else {
                        skipChunk_native(oldStateFD, header.chunkSize);
                    }
                }
            }
        }

        // Then go through and do the rest that we haven't done.
        for (Map.Entry<String,BackupHelper> entry: helpers.entrySet()) {
            header.keyPrefix = entry.getKey();
            Log.d(TAG, "handling new helper '" + header.keyPrefix + "'");
            BackupHelper helper = entry.getValue();
            doOneBackup(oldState, data, newState, header, helper);
        }
    }

    private void doOneBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
            ParcelFileDescriptor newState, Header header, BackupHelper helper) 
            throws IOException {
        int err;
        FileDescriptor newStateFD = newState.getFileDescriptor();

        // allocate space for the header in the file
        int pos = allocateHeader_native(header, newStateFD);
        if (pos < 0) {
            throw new IOException("allocateHeader_native failed (error " + pos + ")");
        }

        data.setKeyPrefix(header.keyPrefix);

        // do the backup
        helper.performBackup(oldState, data, newState);

        // fill in the header (seeking back to pos).  The file pointer will be returned to
        // where it was at the end of performBackup.  Header.chunkSize will not be filled in.
        err = writeHeader_native(header, newStateFD, pos);
        if (err != 0) {
            throw new IOException("writeHeader_native failed (error " + err + ")");
        }
    }

    public void performRestore(BackupDataInput input, int appVersionCode,
            ParcelFileDescriptor newState)
            throws IOException {
        boolean alreadyComplained = false;

        BackupDataInputStream stream = new BackupDataInputStream(input);
        while (input.readNextHeader()) {

            String rawKey = input.getKey();
            int pos = rawKey.indexOf(':');
            if (pos > 0) {
                String prefix = rawKey.substring(0, pos);
                BackupHelper helper = mHelpers.get(prefix);
                if (helper != null) {
                    stream.dataSize = input.getDataSize();
                    stream.key = rawKey.substring(pos+1);
                    helper.restoreEntity(stream);
                } else {
                    if (!alreadyComplained) {
                        Log.w(TAG, "Couldn't find helper for: '" + rawKey + "'");
                        alreadyComplained = true;
                    }
                }
            } else {
                if (!alreadyComplained) {
                    Log.w(TAG, "Entity with no prefix: '" + rawKey + "'");
                    alreadyComplained = true;
                }
            }
            input.skipEntityData(); // In case they didn't consume the data.
        }

        // Write out the state files -- mHelpers is a TreeMap, so the order is well defined.
        for (BackupHelper helper: mHelpers.values()) {
            helper.writeNewStateDescription(newState);
        }
    }

    private static native int readHeader_native(Header h, FileDescriptor fd);
    private static native int skipChunk_native(FileDescriptor fd, int bytesToSkip);

    private static native int allocateHeader_native(Header h, FileDescriptor fd);
    private static native int writeHeader_native(Header h, FileDescriptor fd, int pos);
}

