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

import android.app.Instrumentation;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.test.internal.runner.listener.InstrumentationRunListener;
import android.text.TextUtils;
import android.util.Log;

import junit.framework.TestCase;

import org.junit.runner.Description;
import org.junit.runner.notification.RunListener;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.Class;
import java.lang.ReflectiveOperationException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.Authenticator;
import java.net.CookieHandler;
import java.net.ResponseCache;
import java.text.DateFormat;
import java.util.Locale;
import java.util.Properties;
import java.util.TimeZone;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

/**
 * A {@link RunListener} for CTS. Sets the system properties necessary for many
 * core tests to run. This is needed because there are some core tests that need
 * writing access to the file system.
 * Finally, we add a means to free memory allocated by a TestCase after its
 * execution.
 */
public class CtsTestRunListener extends InstrumentationRunListener {

    private static final String TAG = "CtsTestRunListener";

    private TestEnvironment mEnvironment;
    private Class<?> lastClass;

    @Override
    public void testRunStarted(Description description) throws Exception {
        mEnvironment = new TestEnvironment(getInstrumentation().getTargetContext());

        // We might want to move this to /sdcard, if is is mounted/writable.
        File cacheDir = getInstrumentation().getTargetContext().getCacheDir();
        System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());

        // attempt to disable keyguard, if current test has permission to do so
        // TODO: move this to a better place, such as InstrumentationTestRunner
        // ?
        if (getInstrumentation().getContext().checkCallingOrSelfPermission(
                android.Manifest.permission.DISABLE_KEYGUARD)
                == PackageManager.PERMISSION_GRANTED) {
            Log.i(TAG, "Disabling keyguard");
            KeyguardManager keyguardManager =
                    (KeyguardManager) getInstrumentation().getContext().getSystemService(
                            Context.KEYGUARD_SERVICE);
            keyguardManager.newKeyguardLock("cts").disableKeyguard();
        } else {
            Log.i(TAG, "Test lacks permission to disable keyguard. " +
                    "UI based tests may fail if keyguard is up");
        }
    }

    @Override
    public void testStarted(Description description) throws Exception {
        if (description.getTestClass() != lastClass) {
            lastClass = description.getTestClass();
            printMemory(description.getTestClass());
        }

        mEnvironment.reset();
    }

    @Override
    public void testFinished(Description description) {
        // no way to implement this in JUnit4...
        // offending test cases that need this logic should probably be cleaned
        // up individually
        // if (test instanceof TestCase) {
        // cleanup((TestCase) test);
        // }
    }

    /**
     * Dumps some memory info.
     */
    private void printMemory(Class<?> testClass) {
        Runtime runtime = Runtime.getRuntime();

        long total = runtime.totalMemory();
        long free = runtime.freeMemory();
        long used = total - free;

        Log.d(TAG, "Total memory  : " + total);
        Log.d(TAG, "Used memory   : " + used);
        Log.d(TAG, "Free memory   : " + free);

        String tempdir = System.getProperty("java.io.tmpdir", "");
        if (!TextUtils.isEmpty(tempdir)) {
            String[] commands = {"df", tempdir};
            BufferedReader in = null;
            try {
                Process proc = runtime.exec(commands);
                in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    Log.d(TAG, line);
                }
            } catch (IOException e) {
                // Well, we tried
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        // Meh
                    }
                }
            }
        }

        Log.d(TAG, "Now executing : " + testClass.getName());
    }

    /**
     * Nulls all non-static reference fields in the given test class. This
     * method helps us with those test classes that don't have an explicit
     * tearDown() method. Normally the garbage collector should take care of
     * everything, but since JUnit keeps references to all test cases, a little
     * help might be a good idea.
     */
    private void cleanup(TestCase test) {
        Class<?> clazz = test.getClass();

        while (clazz != TestCase.class) {
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Field f = fields[i];
                if (!f.getType().isPrimitive() &&
                        !Modifier.isStatic(f.getModifiers())) {
                    try {
                        f.setAccessible(true);
                        f.set(test, null);
                    } catch (Exception ignored) {
                        // Nothing we can do about it.
                    }
                }
            }

            clazz = clazz.getSuperclass();
        }
    }

    // http://code.google.com/p/vogar/source/browse/trunk/src/vogar/target/TestEnvironment.java
    static class TestEnvironment {
        private static final Field sDateFormatIs24HourField;
        static {
            try {
                Class<?> dateFormatClass = Class.forName("java.text.DateFormat");
                sDateFormatIs24HourField = dateFormatClass.getDeclaredField("is24Hour");
            } catch (ReflectiveOperationException e) {
                throw new AssertionError("Missing DateFormat.is24Hour", e);
            }
        }

        private final Locale mDefaultLocale;
        private final TimeZone mDefaultTimeZone;
        private final HostnameVerifier mHostnameVerifier;
        private final SSLSocketFactory mSslSocketFactory;
        private final Properties mProperties = new Properties();
        private final Boolean mDefaultIs24Hour;

        TestEnvironment(Context context) {
            mDefaultLocale = Locale.getDefault();
            mDefaultTimeZone = TimeZone.getDefault();
            mHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
            mSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();

            mProperties.setProperty("user.home", "");
            mProperties.setProperty("java.io.tmpdir", context.getCacheDir().getAbsolutePath());
            // The CDD mandates that devices that support WiFi are the only ones that will have
            // multicast.
            PackageManager pm = context.getPackageManager();
            mProperties.setProperty("android.cts.device.multicast",
                    Boolean.toString(pm.hasSystemFeature(PackageManager.FEATURE_WIFI)));
            mDefaultIs24Hour = getDateFormatIs24Hour();
        }

        void reset() {
            System.setProperties(null);
            System.setProperties(mProperties);
            Locale.setDefault(mDefaultLocale);
            TimeZone.setDefault(mDefaultTimeZone);
            Authenticator.setDefault(null);
            CookieHandler.setDefault(null);
            ResponseCache.setDefault(null);
            HttpsURLConnection.setDefaultHostnameVerifier(mHostnameVerifier);
            HttpsURLConnection.setDefaultSSLSocketFactory(mSslSocketFactory);
            setDateFormatIs24Hour(mDefaultIs24Hour);
        }

        private static Boolean getDateFormatIs24Hour() {
            try {
                return (Boolean) sDateFormatIs24HourField.get(null);
            } catch (ReflectiveOperationException e) {
                throw new AssertionError("Unable to get java.text.DateFormat.is24Hour", e);
            }
        }

        private static void setDateFormatIs24Hour(Boolean value) {
            try {
                sDateFormatIs24HourField.set(null, value);
            } catch (ReflectiveOperationException e) {
                throw new AssertionError("Unable to set java.text.DateFormat.is24Hour", e);
            }
        }
    }

}
