/*
 * Copyright (C) 2011 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 com.android.tradefed.targetprep;

import com.android.ddmlib.Log;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;

import java.io.File;
import java.util.Collection;
import java.util.LinkedList;

/**
 * A {@link ITargetPreparer} that attempts to push any number of files from any host path to any
 * device path.
 * <p />
 * Should be performed *after* a new build is flashed, and *after* DeviceSetup is run (if enabled)
 */
@OptionClass(alias = "push-file")
public class PushFilePreparer implements ITargetPreparer {
    private static final String LOG_TAG = "PushFilePreparer";

    @Option(name="push", description=
            "A push-spec, formatted as '/path/to/srcfile.txt->/path/to/destfile.txt' or " +
            "'/path/to/srcfile.txt->/path/to/destdir/'. May be repeated.")
    private Collection<String> mPushSpecs = new LinkedList<String>();

    @Option(name="post-push", description=
            "A command to run on the device (with `adb shell (yourcommand)`) after all pushes " +
            "have been attempted.  Will not be run if a push fails with abort-on-push-failure " +
            "enabled.  May be repeated.")
    private Collection<String> mPostPushCommands = new LinkedList<String>();

    @Option(name="abort-on-push-failure", description=
            "If false, continue if pushes fail.  If true, abort the Invocation on any failure.")
    private boolean mAbortOnFailure = true;

    /**
     * Set abort on failure.  Exposed for testing.
     */
    void setAbortOnFailure(boolean value) {
        mAbortOnFailure = value;
    }

    /**
     * Set pushspecs.  Exposed for testing.
     */
    void setPushSpecs(Collection<String> pushspecs) {
        mPushSpecs = pushspecs;
    }

    /**
     * Set post-push commands.  Exposed for testing.
     */
    void setPostPushCommands(Collection<String> commands) {
        mPostPushCommands = commands;
    }

    /**
     * Helper method to only throw if mAbortOnFailure is enabled.  Callers should behave as if this
     * method may return.
     */
    private void fail(String message) throws TargetSetupError {
        if (mAbortOnFailure) {
            throw new TargetSetupError(message);
        } else {
            // Log the error and return
            Log.w(LOG_TAG, message);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError, BuildError,
            DeviceNotAvailableException {
        for (String pushspec : mPushSpecs) {
            String[] pair = pushspec.split("->");
            Log.d(LOG_TAG, String.format("Trying to push local '%s' to remote '%s'", pair[0],
                    pair[1]));
            if (pair.length != 2) {
                fail(String.format("Invalid pushspec: '%s'"));
                continue;
            }

            File src = new File(pair[0]);
            if (!src.exists()) {
                fail(String.format("Local source file '%s' does not exist", pair[0]));
                continue;
            }

            if (!device.pushFile(src, pair[1])) {
                fail(String.format("Failed to push local '%s' to remote '%s'", pair[0], pair[1]));
                continue;
            }
        }

        for (String command : mPostPushCommands) {
            device.executeShellCommand(command);
        }
    }
}

