/*
 * Copyright (C) 2008 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.cts;

import com.android.ddmlib.MultiLineReceiver;

import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;

/**
 * Class which holds signature check package content.
 */
public class SignatureCheckPackage extends TestPackage {

    private static final String CHECK_API_APP_PACKAGE_NAME = "android.tests.sigtest";
    private static final String MISMATCH_CLASS_SIGNATURE = "mismatch_class_signature";
    private static final String MISSING_INTERFACE = "missing_interface";
    private static final String MISSING_FIELD = "missing_field";
    private static final String MISMATCH_INTERFACE_SIGNATURE = "mismatch_interface_signature";
    private static final String MISMATCH_FIELD_SIGNATURE = "mismatch_field_signature";
    private static final String MISSING_METHOD = "missing_method";
    private static final String MISMATCH_METHOD_SIGNATURE = "mismatch_method_signature";
    private static final String MISSING_CLASS = "missing_class";
    private static final String CAUGHT_EXCEPTION = "caught_exception";
    private static final String ACTION_CHECKAPI = "checkapi";

    private ArrayList<String> mAPICheckResult;

    /**
     * Construct a Signature check package with given necessary information.
     *
     * @param instrumentationRunner The instrumentation runner.
     * @param testPkgBinaryName The binary name of the TestPackage.
     * @param targetNameSpace The package name space of the dependent package, if available.
     * @param targetBinaryName The binary name of the dependent package, if available.
     * @param version The version of the CTS Host allowed.
     * @param androidVersion The version of the Android platform allowed.
     * @param jarPath The host controller's jar path and file.
     * @param appNameSpace The package name space used to uninstall the TestPackage.
     * @param appPackageName The Java package name of the test package.
     */
    public SignatureCheckPackage(final String instrumentationRunner,
            final String testPkgBinaryName, final String targetNameSpace,
            final String targetBinaryName, final String version,
            final String androidVersion, final String jarPath, final String appNameSpace,
            final String appPackageName) throws NoSuchAlgorithmException {
        super(instrumentationRunner, testPkgBinaryName, targetNameSpace, targetBinaryName, version,
                androidVersion, jarPath, appNameSpace, appPackageName, null);
    }

    /**
     * Run the package over the device.
     *
     * @param device The device to run the package.
     * @param javaPkgName The java package name.
     * @param testSesssionLog the TestSessionLog for this TestSession.
     */
    @Override
    public void run(final TestDevice device, final String javaPkgName,
            TestSessionLog testSesssionLog) throws DeviceDisconnectedException,
            InvalidNameSpaceException, InvalidApkPathException {
        Test test = getTests().iterator().next();
        if ((test != null) && (test.getResult().isNotExecuted())) {

            ArrayList<String> result = startSignatureTest(device);
            if (result != null) {
                StringBuffer formattedResult = new StringBuffer();
                int resultCode = processSignatureResult(result, formattedResult);

                String resultStr = formattedResult.toString();
                if (resultCode == CtsTestResult.CODE_PASS) {
                    resultStr = null;
                }

                test.setResult(new CtsTestResult(resultCode, resultStr, null));
            }
        }
    }


    /**
     * Start signature test.
     *
     * @param device the device under test.
     * @return test result
     */
    public ArrayList<String> startSignatureTest(TestDevice device)
                throws DeviceDisconnectedException, InvalidNameSpaceException,
                InvalidApkPathException {
        Log.d("installing APICheck apk");
        mAPICheckResult = new ArrayList<String>();
        // TODO: This is non-obvious and should be cleaned up
        device.setRuntimeListener(device);

        String apkPath =
            HostConfig.getInstance().getCaseRepository().getApkPath(getAppBinaryName());
        if (!HostUtils.isFileExist(apkPath)) {
            Log.e("File doesn't exist: " + apkPath, null);
            return null;
        }

        device.installAPK(apkPath);
        device.waitForCommandFinish();

        runSignatureTestCommand(device);
        device.waitForCommandFinish();

        device.uninstallAPK(CHECK_API_APP_PACKAGE_NAME);
        device.waitForCommandFinish();

        device.removeRuntimeListener();

        return mAPICheckResult;
    }

    /**
     * Run signature test command.
     *
     * @param device the device to run against.
     */
    private void runSignatureTestCommand(TestDevice device)
                throws DeviceDisconnectedException {
        Log.i("Checking API... ");
        Log.i("This might take several minutes, please be patient...");

        final String commandStr = "am instrument -w -e bundle true "
            + getAppPackageName() + "/" + getInstrumentationRunner();
        Log.d(commandStr);

        device.startActionTimer(ACTION_CHECKAPI,
                HostConfig.Ints.signatureTestTimeoutMs.value());
        device.executeShellCommand(commandStr, new SignatureTestResultObserver(device));
    }

    /**
     * Signature result observer.
     */
    class SignatureTestResultObserver extends MultiLineReceiver {

        private final TestDevice device;

        public SignatureTestResultObserver(TestDevice td) {
            this.device = td;
        }

        /** {@inheritDoc} */
        @Override
        public void processNewLines(String[] lines) {
            for (int i = 0; i < lines.length; i++) {
                mAPICheckResult.add(lines[i]);
            }
        }

        /** {@inheritDoc} */
        public boolean isCancelled() {
            return false;
        }

        /** {@inheritDoc} */
        @Override
        public void done() {
            device.stopActionTimer();
            device.notifyExternalTestComplete();
        }
    }

    /**
     * Process signature result.
     *
     * @param apiCheckResult The result of API checking.
     * @param formattedResult The formated result of API checking.
     * @return  PASS or FAIL according to the check result.
     */
    public int processSignatureResult(ArrayList<String> apiCheckResult,
                StringBuffer formattedResult) {

        HashMap<String, String> resMap = new HashMap<String, String>();
        for (String res : apiCheckResult) {
            Matcher matcher = TestDevice.INSTRUMENT_RESULT_PATTERN.matcher(res);
            if (matcher.matches()) {
                resMap.put(matcher.group(1), matcher.group(2));
            }
        }

        String result = resMap.get("result");
        if (result == null) {
            CUIOutputStream.println("API Check TIMEOUT.");
            return CtsTestResult.CODE_TIMEOUT;
        }

        if (result.equals("true")) {
            CUIOutputStream.println("API Check PASS.");
            return CtsTestResult.CODE_PASS;
        }

        CUIOutputStream.println("API Check FAIL!");
        final String leadingSpace = "      ";
        for (String key : resMap.keySet()) {
            if (key.equals("result")) {
                // ignore the result string
                continue;
            }

            String resStr = resMap.get(key);
            if ((resStr != null) && (resStr.length() > 2)) {
                formattedResult.append(key +":\n");
                if (MISMATCH_CLASS_SIGNATURE.equals(key)
                        || MISMATCH_INTERFACE_SIGNATURE.equals(key)
                        || MISMATCH_FIELD_SIGNATURE.equals(key)
                        || MISSING_FIELD.equals(key)
                        || MISSING_METHOD.equals(key)
                        || MISMATCH_METHOD_SIGNATURE.equals(key)) {
                    resStr = resStr.substring(1, resStr.length() - 1);
                    String[] details = resStr.split("\\), ");
                    for (String detail : details) {
                        formattedResult.append(leadingSpace + detail + ")\n");
                    }
                    formattedResult.append("\n");
                } else if (MISSING_INTERFACE.equals(key)
                        || MISSING_CLASS.equals(key)) {
                    resStr = resStr.substring(1, resStr.length() - 1);
                    String[] details = resStr.split(", ");
                    for (String detail : details) {
                        formattedResult.append(leadingSpace + detail + "\n");
                    }
                    formattedResult.append("\n");
                } else if (CAUGHT_EXCEPTION.equals(key)) {
                    resStr = resStr.substring(1, resStr.length() - 1);
                    formattedResult.append(resStr);
                    formattedResult.append("\n");
                }
            }
        }

        return CtsTestResult.CODE_FAIL;
    }
}

