/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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.ide.eclipse.adt.internal.launch.junit;

import com.android.ddmlib.IDevice;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.launch.DelayedLaunchInfo;
import com.android.ide.eclipse.adt.internal.launch.IAndroidLaunchAction;
import com.android.ide.eclipse.adt.internal.launch.LaunchMessages;
import com.android.ide.eclipse.adt.internal.launch.junit.runtime.AndroidJUnitLaunchInfo;
import com.android.ide.eclipse.adt.internal.launch.junit.runtime.RemoteAdtTestRunner;
import com.google.common.base.Joiner;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
import org.eclipse.swt.widgets.Display;

import java.util.Collection;

/**
 * A launch action that executes a instrumentation test run on an Android device.
 */
class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
    private static final Joiner JOINER = Joiner.on(',').skipNulls();
    private final AndroidJUnitLaunchInfo mLaunchInfo;

    /**
     * Creates a AndroidJUnitLaunchAction.
     *
     * @param launchInfo the {@link AndroidJUnitLaunchInfo} for the JUnit run
     */
    public AndroidJUnitLaunchAction(AndroidJUnitLaunchInfo launchInfo) {
        mLaunchInfo = launchInfo;
    }

    /**
     * Launch a instrumentation test run on given Android devices.
     * Reuses JDT JUnit launch delegate so results can be communicated back to JDT JUnit UI.
     * <p/>
     * Note: Must be executed on non-UI thread.
     *
     * @see IAndroidLaunchAction#doLaunchActions(DelayedLaunchInfo, IDevice)
     */
    @Override
    public boolean doLaunchAction(DelayedLaunchInfo info, Collection<IDevice> devices) {
        String msg = String.format(LaunchMessages.AndroidJUnitLaunchAction_LaunchInstr_2s,
                mLaunchInfo.getRunner(), JOINER.join(devices));
        AdtPlugin.printToConsole(info.getProject(), msg);

        try {
           mLaunchInfo.setDebugMode(info.isDebugMode());
           mLaunchInfo.setDevices(devices);
           JUnitLaunchDelegate junitDelegate = new JUnitLaunchDelegate(mLaunchInfo);
           final String mode = info.isDebugMode() ? ILaunchManager.DEBUG_MODE :
               ILaunchManager.RUN_MODE;

           junitDelegate.launch(info.getLaunch().getLaunchConfiguration(), mode, info.getLaunch(),
                   info.getMonitor());

           // TODO: need to add AMReceiver-type functionality somewhere
        } catch (CoreException e) {
            AdtPlugin.printErrorToConsole(info.getProject(),
                    LaunchMessages.AndroidJUnitLaunchAction_LaunchFail);
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getLaunchDescription() {
        return String.format(LaunchMessages.AndroidJUnitLaunchAction_LaunchDesc_s,
                mLaunchInfo.getRunner());
    }

    /**
     * Extends the JDT JUnit launch delegate to allow for JUnit UI reuse.
     */
    private static class JUnitLaunchDelegate extends JUnitLaunchConfigurationDelegate {

        private AndroidJUnitLaunchInfo mLaunchInfo;

        public JUnitLaunchDelegate(AndroidJUnitLaunchInfo launchInfo) {
            mLaunchInfo = launchInfo;
        }

        /* (non-Javadoc)
         * @see org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
         */
        @Override
        public synchronized void launch(ILaunchConfiguration configuration, String mode,
                ILaunch launch, IProgressMonitor monitor) throws CoreException {
            // TODO: is progress monitor adjustment needed here?
            super.launch(configuration, mode, launch, monitor);
        }

        /**
         * {@inheritDoc}
         * @see org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate#verifyMainTypeName(org.eclipse.debug.core.ILaunchConfiguration)
         */
        @Override
        public String verifyMainTypeName(ILaunchConfiguration configuration) {
            return "com.android.ide.eclipse.adt.junit.internal.runner.RemoteAndroidTestRunner"; //$NON-NLS-1$
        }

        /**
         * Overrides parent to return a VM Runner implementation which launches a thread, rather
         * than a separate VM process
         */
        @Override
        public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) {
            return new VMTestRunner(mLaunchInfo);
        }

        /**
         * {@inheritDoc}
         * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getLaunch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
         */
        @Override
        public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) {
            return mLaunchInfo.getLaunch();
        }
    }

    /**
     * Provides a VM runner implementation which starts a inline implementation of a launch process
     */
    private static class VMTestRunner implements IVMRunner {

        private final AndroidJUnitLaunchInfo mJUnitInfo;

        VMTestRunner(AndroidJUnitLaunchInfo info) {
            mJUnitInfo = info;
        }

        /**
         * {@inheritDoc}
         * @throws CoreException
         */
        @Override
        public void run(final VMRunnerConfiguration config, ILaunch launch,
                IProgressMonitor monitor) throws CoreException {

            TestRunnerProcess runnerProcess =
                new TestRunnerProcess(config, mJUnitInfo);
            launch.addProcess(runnerProcess);
            runnerProcess.run();
        }
    }

    /**
     * Launch process that executes the tests.
     */
    private static class TestRunnerProcess implements IProcess  {

        private final VMRunnerConfiguration mRunConfig;
        private final AndroidJUnitLaunchInfo mJUnitInfo;
        private RemoteAdtTestRunner mTestRunner = null;
        private boolean mIsTerminated = false;

        TestRunnerProcess(VMRunnerConfiguration runConfig, AndroidJUnitLaunchInfo info) {
            mRunConfig = runConfig;
            mJUnitInfo = info;
        }

        /* (non-Javadoc)
         * @see org.eclipse.debug.core.model.IProcess#getAttribute(java.lang.String)
         */
        @Override
        public String getAttribute(String key) {
            return null;
        }

        /**
         * {@inheritDoc}
         * @see org.eclipse.debug.core.model.IProcess#getExitValue()
         */
        @Override
        public int getExitValue() {
            return 0;
        }

        /* (non-Javadoc)
         * @see org.eclipse.debug.core.model.IProcess#getLabel()
         */
        @Override
        public String getLabel() {
            return mJUnitInfo.getLaunch().getLaunchMode();
        }

        /* (non-Javadoc)
         * @see org.eclipse.debug.core.model.IProcess#getLaunch()
         */
        @Override
        public ILaunch getLaunch() {
            return mJUnitInfo.getLaunch();
        }

        /* (non-Javadoc)
         * @see org.eclipse.debug.core.model.IProcess#getStreamsProxy()
         */
        @Override
        public IStreamsProxy getStreamsProxy() {
            return null;
        }

        /* (non-Javadoc)
         * @see org.eclipse.debug.core.model.IProcess#setAttribute(java.lang.String,
         * java.lang.String)
         */
        @Override
        public void setAttribute(String key, String value) {
            // ignore
        }

        /* (non-Javadoc)
         * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
         */
        @Override
        public Object getAdapter(Class adapter) {
            return null;
        }

        /* (non-Javadoc)
         * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
         */
        @Override
        public boolean canTerminate() {
            return true;
        }

        /* (non-Javadoc)
         * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
         */
        @Override
        public boolean isTerminated() {
            return mIsTerminated;
        }

        /**
         * {@inheritDoc}
         * @see org.eclipse.debug.core.model.ITerminate#terminate()
         */
        @Override
        public void terminate() {
            if (mTestRunner != null) {
                mTestRunner.terminate();
            }
            mIsTerminated = true;
        }

        /**
         * Launches a test runner that will communicate results back to JDT JUnit UI.
         * <p/>
         * Must be executed on a non-UI thread.
         */
        public void run() {
            if (Display.getCurrent() != null) {
                AdtPlugin.log(IStatus.ERROR, "Adt test runner executed on UI thread");
                AdtPlugin.printErrorToConsole(mJUnitInfo.getProject(),
                        "Test launch failed due to internal error: Running tests on UI thread");
                terminate();
                return;
            }
            mTestRunner = new RemoteAdtTestRunner();
            mTestRunner.runTests(mRunConfig.getProgramArguments(), mJUnitInfo);
        }
    }
}

