/*
 * 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 android.signature.cts.api;

import android.os.Bundle;
import android.signature.cts.ApiDocumentParser;
import android.signature.cts.ApiComplianceChecker;
import android.signature.cts.FailureType;
import android.signature.cts.JDiffClassDescription;
import android.signature.cts.ReflectionHelper;
import android.signature.cts.ResultObserver;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import org.xmlpull.v1.XmlPullParserException;
import repackaged.android.test.InstrumentationTestCase;
import repackaged.android.test.InstrumentationTestRunner;

import static android.signature.cts.CurrentApi.API_FILE_DIRECTORY;

/**
 * Performs the signature check via a JUnit test.
 */
public class SignatureTest extends InstrumentationTestCase {

    private static final String TAG = SignatureTest.class.getSimpleName();

    /**
     * A set of class names that are inaccessible for some reason.
     */
    private static final Set<String> KNOWN_INACCESSIBLE_CLASSES = new HashSet<>();

    static {
        // TODO(b/63383787) - These classes, which are nested annotations with @Retention(SOURCE)
        // are removed from framework.dex for an as yet unknown reason.
        KNOWN_INACCESSIBLE_CLASSES.add("android.content.pm.PackageManager.PermissionFlags");
        KNOWN_INACCESSIBLE_CLASSES.add("android.os.UserManager.UserRestrictionSource");
        KNOWN_INACCESSIBLE_CLASSES.add(
                "android.service.persistentdata.PersistentDataBlockManager.FlashLockState");
    }

    private TestResultObserver mResultObserver;

    private String[] expectedApiFiles;
    private String[] unexpectedApiFiles;

    private class TestResultObserver implements ResultObserver {

        boolean mDidFail = false;

        StringBuilder mErrorString = new StringBuilder();

        @Override
        public void notifyFailure(FailureType type, String name, String errorMessage) {
            mDidFail = true;
            mErrorString.append("\n");
            mErrorString.append(type.toString().toLowerCase());
            mErrorString.append(":\t");
            mErrorString.append(name);
            mErrorString.append("\tError: ");
            mErrorString.append(errorMessage);
        }
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mResultObserver = new TestResultObserver();

        // Get the arguments passed to the instrumentation.
        Bundle instrumentationArgs =
                ((InstrumentationTestRunner) getInstrumentation()).getArguments();

        expectedApiFiles = getCommaSeparatedList(instrumentationArgs, "expected-api-files");
        unexpectedApiFiles = getCommaSeparatedList(instrumentationArgs, "unexpected-api-files");
    }

    private String[] getCommaSeparatedList(Bundle instrumentationArgs, String key) {
        String argument = instrumentationArgs.getString(key);
        if (argument == null) {
            return new String[0];
        }
        return argument.split(",");
    }

    /**
     * Tests that the device's API matches the expected set defined in xml.
     * <p/>
     * Will check the entire API, and then report the complete list of failures
     */
    public void testSignature() {
        try {
            Set<JDiffClassDescription> unexpectedClasses = loadUnexpectedClasses();
            for (JDiffClassDescription classDescription : unexpectedClasses) {
                Class<?> unexpectedClass = findUnexpectedClass(classDescription);
                if (unexpectedClass != null) {
                    mResultObserver.notifyFailure(
                            FailureType.UNEXPECTED_CLASS,
                            classDescription.getAbsoluteClassName(),
                            "Class should not be accessible to this APK");
                }
            }

            ApiComplianceChecker complianceChecker = new ApiComplianceChecker(mResultObserver);
            ApiDocumentParser apiDocumentParser = new ApiDocumentParser(
                    TAG, new ApiDocumentParser.Listener() {
                @Override
                public void completedClass(JDiffClassDescription classDescription) {
                    // Ignore classes that are known to be inaccessible.
                    if (KNOWN_INACCESSIBLE_CLASSES.contains(classDescription.getAbsoluteClassName())) {
                        return;
                    }

                    // Ignore unexpected classes that are in the API definition.
                    if (!unexpectedClasses.contains(classDescription)) {
                        complianceChecker.checkSignatureCompliance(classDescription);
                    }
                }
            });

            for (String expectedApiFile : expectedApiFiles) {
                File file = new File(API_FILE_DIRECTORY + "/" + expectedApiFile);
                apiDocumentParser.parse(new FileInputStream(file));
            }
        } catch (Exception e) {
            mResultObserver.notifyFailure(FailureType.CAUGHT_EXCEPTION, e.getMessage(),
                    e.getMessage());
        }
        if (mResultObserver.mDidFail) {
            StringBuilder errorString = mResultObserver.mErrorString;
            ClassLoader classLoader = getClass().getClassLoader();
            errorString.append("\nClassLoader hierarchy\n");
            while (classLoader != null) {
                errorString.append("    ").append(classLoader).append("\n");
                classLoader = classLoader.getParent();
            }
            fail(errorString.toString());
        }
    }

    private Class<?> findUnexpectedClass(JDiffClassDescription classDescription) {
        try {
            return ReflectionHelper.findMatchingClass(classDescription);
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    private Set<JDiffClassDescription> loadUnexpectedClasses()
            throws IOException, XmlPullParserException {

        Set<JDiffClassDescription> unexpectedClasses = new TreeSet<>(
                Comparator.comparing(JDiffClassDescription::getAbsoluteClassName));
        ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG,
                new ApiDocumentParser.Listener() {
                    @Override
                    public void completedClass(JDiffClassDescription classDescription) {
                        unexpectedClasses.add(classDescription);
                    }
                });
        for (String expectedApiFile : unexpectedApiFiles) {
            File file = new File(API_FILE_DIRECTORY + "/" + expectedApiFile);
            apiDocumentParser.parse(new FileInputStream(file));
        }
        return unexpectedClasses;
    }
}
