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

import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.ddmlib.testrunner.TestResult;
import com.android.ddmlib.testrunner.TestResult.TestStatus;
import com.android.ddmlib.testrunner.TestRunResult;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.CollectingOutputReceiver;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.CollectingTestListener;
import com.android.tradefed.testtype.DeviceTestCase;
import com.android.tradefed.testtype.IBuildReceiver;

import java.io.FileNotFoundException;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class BaseDumpsysTest extends DeviceTestCase implements IBuildReceiver {
    protected static final String TAG = "DumpsysHostTest";

    private static final String TEST_RUNNER = "android.support.test.runner.AndroidJUnitRunner";

    /**
     * A reference to the device under test.
     */
    protected ITestDevice mDevice;

    protected IBuildInfo mCtsBuild;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mDevice = getDevice();
    }

    @Override
    public void setBuild(IBuildInfo buildInfo) {
        mCtsBuild = buildInfo;
    }

    protected static long assertInteger(String input) {
        try {
            return Long.parseLong(input);
        } catch (NumberFormatException e) {
            fail("Expected an integer but found \"" + input + "\"");
            // Won't be hit, above throws AssertException
            return -1;
        }
    }

    protected static long assertNonNegativeInteger(String input) {
        try {
            final long result = Long.parseLong(input);
            assertTrue("Expected non-negative, but was: " + result, result >= 0);

            return result;
        } catch (NumberFormatException e) {
            fail("Expected an integer but found \"" + input + "\"");
            // Won't be hit, above throws AssertException
            return -1;
        }
    }

    protected static long assertPositiveInteger(String input) {
        try {
            final long result = Long.parseLong(input);
            assertTrue("Expected positive, but was: " + result, result > 0);

            return result;
        } catch (NumberFormatException e) {
            fail("Expected an integer but found \"" + input + "\"");
            // Won't be hit, above throws AssertException
            return -1;
        }
    }

    protected static void assertMinAvgMax(String min, String avg, String max, boolean checkAvg) {
        final long lMin = assertNonNegativeInteger(min);
        final long lAvg = assertNonNegativeInteger(avg);
        final long lMax = assertNonNegativeInteger(max);

        if (checkAvg) {
            assertTrue("min [" + min + "] <= avg [" + avg + "]", lMin <= lAvg);
            assertTrue("avg [" + avg + "] <= max [" + max + "]", lAvg <= lMax);
        } else {
            // There was a bug in the average calculation, so we can't check the average
            // from the last N hour stats, which may be generated on with the buggy logic.
            assertTrue("min [" + min + "] <= max [" + max + "]", lMin <= lMax);
        }
    }

    protected static void assertLesserOrEqual(String lesser, String greater) {
        final long lLesser = assertNonNegativeInteger(lesser);
        final long lGreater = assertNonNegativeInteger(greater);

        assertTrue("[" + lesser + "] <= [" + greater + "]", lLesser <= lGreater);
    }

    protected static double assertDouble(String input) {
        try {
            return Double.parseDouble(input);
        } catch (NumberFormatException e) {
            fail("Expected a double but found \"" + input + "\"");
            return -1;
        }
    }

    protected static void assertSeenTag(Set<String> seenTags, String tag) {
        assertTrue("No line starting with \"" + tag + ",\"", seenTags.contains(tag));
    }


    /**
     * Install a device side test package.
     *
     * @param appFileName Apk file name, such as "CtsNetStatsApp.apk".
     * @param grantPermissions whether to give runtime permissions.
     */
    protected void installPackage(String appFileName, boolean grantPermissions)
            throws FileNotFoundException, DeviceNotAvailableException {
        CLog.d("Installing app " + appFileName);
        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
        final String result = getDevice().installPackage(
                buildHelper.getTestFile(appFileName), true, grantPermissions);
        assertNull("Failed to install " + appFileName + ": " + result, result);
    }

    /**
     * Run a device side test.
     *
     * @param pkgName Test package name, such as "com.android.server.cts.netstats".
     * @param testClassName Test class name; either a fully qualified name, or "." + a class name.
     * @param testMethodName Test method name.
     * @throws DeviceNotAvailableException
     */
    protected void runDeviceTests(@Nonnull String pkgName,
            @Nullable String testClassName, @Nullable String testMethodName)
            throws DeviceNotAvailableException {
        if (testClassName != null && testClassName.startsWith(".")) {
            testClassName = pkgName + testClassName;
        }

        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
                pkgName, TEST_RUNNER, getDevice().getIDevice());
        if (testClassName != null && testMethodName != null) {
            testRunner.setMethodName(testClassName, testMethodName);
        } else if (testClassName != null) {
            testRunner.setClassName(testClassName);
        }

        CollectingTestListener listener = new CollectingTestListener();
        assertTrue(getDevice().runInstrumentationTests(testRunner, listener));

        final TestRunResult result = listener.getCurrentRunResults();
        if (result.isRunFailure()) {
            throw new AssertionError("Failed to successfully run device tests for "
                    + result.getName() + ": " + result.getRunFailureMessage());
        }
        if (result.getNumTests() == 0) {
            throw new AssertionError("No tests were run on the device");
        }

        if (result.hasFailedTests()) {
            // build a meaningful error message
            StringBuilder errorBuilder = new StringBuilder("On-device tests failed:\n");
            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
                    result.getTestResults().entrySet()) {
                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
                    errorBuilder.append(resultEntry.getKey().toString());
                    errorBuilder.append(":\n");
                    errorBuilder.append(resultEntry.getValue().getStackTrace());
                }
            }
            throw new AssertionError(errorBuilder.toString());
        }
    }

    /**
     * Execute the given command, and find the given pattern and return the resulting
     * {@link Matcher}.
     */
    protected Matcher execCommandAndFind(String command, String pattern) throws Exception {
        final CollectingOutputReceiver receiver = new CollectingOutputReceiver();
        getDevice().executeShellCommand(command, receiver);
        final String output = receiver.getOutput();
        final Matcher matcher = Pattern.compile(pattern).matcher(output);
        assertTrue("Pattern '" + pattern + "' didn't match. Output=\n" + output, matcher.find());
        return matcher;
    }

    /**
     * Execute the given command, find the given pattern, and return the first captured group
     * as a String.
     */
    protected String execCommandAndGetFirstGroup(String command, String pattern) throws Exception {
        final Matcher matcher = execCommandAndFind(command, pattern);
        assertTrue("No group found for pattern '" + pattern + "'", matcher.groupCount() > 0);
        return matcher.group(1);
    }
}
