/*
 * 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 android.annotation.cts.Profile;

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);
    }

    /**
     * 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;
    }
}

