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

import android.app.Instrumentation;
import android.content.Intent;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Environment;
import android.provider.Browser;
import android.test.ActivityInstrumentationTestCase2;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.ClientCertRequestHandler;
import android.webkit.DownloadListener;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClassic;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 *
 * Iterates over a list of URLs from a file and outputs the time to load each.
 */
public class PopularUrlsTest extends ActivityInstrumentationTestCase2<BrowserActivity> {

    private final static String TAG = "PopularUrlsTest";
    private final static String newLine = System.getProperty("line.separator");
    private final static String sInputFile = "popular_urls.txt";
    private final static String sOutputFile = "test_output.txt";
    private final static String sStatusFile = "test_status.txt";
    private final static File sExternalStorage = Environment.getExternalStorageDirectory();

    private final static int PERF_LOOPCOUNT = 10;
    private final static int STABILITY_LOOPCOUNT = 1;
    private final static int PAGE_LOAD_TIMEOUT = 120000; // 2 minutes

    private BrowserActivity mActivity = null;
    private Controller mController = null;
    private Instrumentation mInst = null;
    private CountDownLatch mLatch = new CountDownLatch(1);
    private RunStatus mStatus;
    private boolean pageLoadFinishCalled, pageProgressFull;

    public PopularUrlsTest() {
        super(BrowserActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("about:blank"));
        i.putExtra(Controller.NO_CRASH_RECOVERY, true);
        setActivityIntent(i);
        mActivity = getActivity();
        mController = mActivity.getController();
        mInst = getInstrumentation();
        mInst.waitForIdleSync();

        mStatus = RunStatus.load();
    }

    @Override
    protected void tearDown() throws Exception {
        if (mStatus != null) {
            mStatus.cleanUp();
        }

        super.tearDown();
    }

    BufferedReader getInputStream() throws FileNotFoundException {
        return getInputStream(sInputFile);
    }

    BufferedReader getInputStream(String inputFile) throws FileNotFoundException {
        FileReader fileReader = new FileReader(new File(sExternalStorage, inputFile));
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        return bufferedReader;
    }

    OutputStreamWriter getOutputStream() throws IOException {
        return getOutputStream(sOutputFile);
    }

    OutputStreamWriter getOutputStream(String outputFile) throws IOException {
        return new FileWriter(new File(sExternalStorage, outputFile), mStatus.getIsRecovery());
    }

    /**
     * Gets the browser ready for testing by starting the application
     * and wrapping the WebView's helper clients.
     */
    void setUpBrowser() {
        mInst.runOnMainSync(new Runnable() {
            @Override
            public void run() {
                setupBrowserInternal();
            }
        });
    }

    void setupBrowserInternal() {
        Tab tab = mController.getTabControl().getCurrentTab();
        WebView webView = tab.getWebView();

        webView.setWebChromeClient(new TestWebChromeClient(
                WebViewClassic.fromWebView(webView).getWebChromeClient()) {

            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                if (newProgress >= 100) {
                    if (!pageProgressFull) {
                        // void duplicate calls
                        pageProgressFull  = true;
                        if (pageLoadFinishCalled) {
                            //reset latch and move forward only if both indicators are true
                            resetLatch();
                        }
                    }
                }
            }

            /**
             * Dismisses and logs Javascript alerts.
             */
            @Override
            public boolean onJsAlert(WebView view, String url, String message,
                    JsResult result) {
                String logMsg = String.format("JS Alert '%s' received from %s", message, url);
                Log.w(TAG, logMsg);
                result.confirm();

                return true;
            }

            /**
             * Confirms and logs Javascript alerts.
             */
            @Override
            public boolean onJsConfirm(WebView view, String url, String message,
                    JsResult result) {
                String logMsg = String.format("JS Confirmation '%s' received from %s",
                        message, url);
                Log.w(TAG, logMsg);
                result.confirm();

                return true;
            }

            /**
             * Confirms and logs Javascript alerts, providing the default value.
             */
            @Override
            public boolean onJsPrompt(WebView view, String url, String message,
                    String defaultValue, JsPromptResult result) {
                String logMsg = String.format("JS Prompt '%s' received from %s; " +
                        "Giving default value '%s'", message, url, defaultValue);
                Log.w(TAG, logMsg);
                result.confirm(defaultValue);

                return true;
            }

            /*
             * Skip the unload confirmation
             */
            @Override
            public boolean onJsBeforeUnload(
                    WebView view, String url, String message, JsResult result) {
                result.confirm();
                return true;
            }
        });

        webView.setWebViewClient(new TestWebViewClient(
                WebViewClassic.fromWebView(webView).getWebViewClient()) {

            /**
             * Bypasses and logs errors.
             */
            @Override
            public void onReceivedError(WebView view, int errorCode,
                    String description, String failingUrl) {
                String message = String.format("Error '%s' (%d) loading url: %s",
                        description, errorCode, failingUrl);
                Log.w(TAG, message);
            }

            /**
             * Ignores and logs SSL errors.
             */
            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler,
                    SslError error) {
                Log.w(TAG, "SSL error: " + error);
                handler.proceed();
            }

            /**
             * Ignores and logs SSL client certificate requests.
             */
            @Override
            public void onReceivedClientCertRequest(WebView view, ClientCertRequestHandler handler,
                    String host_and_port) {
                Log.w(TAG, "SSL client certificate request: " + host_and_port);
                handler.cancel();
            }

            /**
             * Ignores http auth with dummy username and password
             */
            @Override
            public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
                    String host, String realm) {
                handler.proceed("user", "passwd");
            }

            /* (non-Javadoc)
             * @see com.android.browser.TestWebViewClient#onPageFinished(android.webkit.WebView, java.lang.String)
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                if (!pageLoadFinishCalled) {
                    pageLoadFinishCalled = true;
                    if (pageProgressFull) {
                        //reset latch and move forward only if both indicators are true
                        resetLatch();
                    }
                }
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (!(url.startsWith("http://") || url.startsWith("https://"))) {
                    Log.v(TAG, String.format("suppressing non-http url scheme: %s", url));
                    return true;
                }
                return super.shouldOverrideUrlLoading(view, url);
            }
        });

        webView.setDownloadListener(new DownloadListener() {

            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition,
                    String mimetype, long contentLength) {
                Log.v(TAG, String.format("Download request ignored: %s", url));
            }
        });
    }

    void resetLatch() {
        if (mLatch.getCount() != 1) {
            Log.w(TAG, "Expecting latch to be 1, but it's not!");
        } else {
            mLatch.countDown();
        }
    }

    void resetForNewPage() {
        mLatch = new CountDownLatch(1);
        pageLoadFinishCalled = false;
        pageProgressFull = false;
    }

    void waitForLoad() throws InterruptedException {
        boolean timedout = !mLatch.await(PAGE_LOAD_TIMEOUT, TimeUnit.MILLISECONDS);
        if (timedout) {
            Log.w(TAG, "page timeout. trying to stop.");
            // try to stop page load
            mInst.runOnMainSync(new Runnable(){
                public void run() {
                    mController.getTabControl().getCurrentTab().getWebView().stopLoading();
                }
            });
            // try to wait for count down latch again
            timedout = !mLatch.await(5000, TimeUnit.MILLISECONDS);
            if (timedout) {
                throw new RuntimeException("failed to stop timedout site, is browser pegged?");
            }
        }
    }

    private static class RunStatus {
        private File mFile;
        private int iteration;
        private int page;
        private String url;
        private boolean isRecovery;
        private boolean allClear;

        private RunStatus(File file) throws IOException {
            mFile = file;
            FileReader input = null;
            BufferedReader reader = null;
            isRecovery = false;
            allClear = false;
            iteration = 0;
            page = 0;
            try {
                input = new FileReader(mFile);
                isRecovery = true;
                reader = new BufferedReader(input);
                String line = reader.readLine();
                if (line == null)
                    return;
                iteration = Integer.parseInt(line);
                line = reader.readLine();
                if (line == null)
                    return;
                page = Integer.parseInt(line);
            } catch (FileNotFoundException ex) {
                return;
            } catch (NumberFormatException nfe) {
                Log.wtf(TAG, "unexpected data in status file, will start from begining");
                return;
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } finally {
                    if (input != null) {
                        input.close();
                    }
                }
            }
        }

        public static RunStatus load() throws IOException {
            return load(sStatusFile);
        }

        public static RunStatus load(String file) throws IOException {
            return new RunStatus(new File(sExternalStorage, file));
        }

        public void write() throws IOException {
            FileWriter output = null;
            if (mFile.exists()) {
                mFile.delete();
            }
            try {
                output = new FileWriter(mFile);
                output.write(iteration + newLine);
                output.write(page + newLine);
                output.write(url + newLine);
            } finally {
                if (output != null) {
                    output.close();
                }
            }
        }

        public void cleanUp() {
            // only perform cleanup when allClear flag is set
            // i.e. when the test was not interrupted by a Java crash
            if (mFile.exists() && allClear) {
                mFile.delete();
            }
        }

        public void resetPage() {
            page = 0;
        }

        public void incrementPage() {
            ++page;
            allClear = true;
        }

        public void incrementIteration() {
            ++iteration;
        }

        public int getPage() {
            return page;
        }

        public int getIteration() {
            return iteration;
        }

        public boolean getIsRecovery() {
            return isRecovery;
        }

        public void setUrl(String url) {
            this.url = url;
            allClear = false;
        }
    }

    /**
     * Loops over a list of URLs, points the browser to each one, and records the time elapsed.
     *
     * @param input the reader from which to get the URLs.
     * @param writer the writer to which to output the results.
     * @param clearCache determines whether the cache is cleared before loading each page
     * @param loopCount the number of times to loop through the list of pages
     * @throws IOException unable to read from input or write to writer.
     * @throws InterruptedException the thread was interrupted waiting for the page to load.
     */
    void loopUrls(BufferedReader input, OutputStreamWriter writer,
            boolean clearCache, int loopCount)
            throws IOException, InterruptedException {
        Tab tab = mController.getTabControl().getCurrentTab();
        WebView webView = tab.getWebView();

        List<String> pages = new LinkedList<String>();

        String page;
        while (null != (page = input.readLine())) {
            if (!TextUtils.isEmpty(page)) {
                pages.add(page);
            }
        }

        Iterator<String> iterator = pages.iterator();
        for (int i = 0; i < mStatus.getPage(); ++i) {
            iterator.next();
        }

        if (mStatus.getIsRecovery()) {
            Log.e(TAG, "Recovering after crash: " + iterator.next());
            mStatus.incrementPage();
        }

        while (mStatus.getIteration() < loopCount) {
            if (clearCache) {
                clearCacheUiThread(webView, true);
            }
            while(iterator.hasNext()) {
                page = iterator.next();
                mStatus.setUrl(page);
                mStatus.write();
                Log.i(TAG, "start: " + page);
                Uri uri = Uri.parse(page);
                final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                intent.putExtra(Browser.EXTRA_APPLICATION_ID,
                    getInstrumentation().getTargetContext().getPackageName());

                long startTime = System.currentTimeMillis();
                resetForNewPage();
                mInst.runOnMainSync(new Runnable() {

                    public void run() {
                        mActivity.onNewIntent(intent);
                    }

                });
                waitForLoad();
                long stopTime = System.currentTimeMillis();

                String url = getUrlUiThread(webView);
                Log.i(TAG, "finish: " + url);

                if (writer != null) {
                    writer.write(page + "|" + (stopTime - startTime) + newLine);
                    writer.flush();
                }

                mStatus.incrementPage();
            }
            mStatus.incrementIteration();
            mStatus.resetPage();
            iterator = pages.iterator();
        }
    }

    public void testLoadPerformance() throws IOException, InterruptedException {
        setUpBrowser();

        OutputStreamWriter writer = getOutputStream();
        try {
            BufferedReader bufferedReader = getInputStream();
            try {
                loopUrls(bufferedReader, writer, true, PERF_LOOPCOUNT);
            } finally {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            }
        } catch (FileNotFoundException fnfe) {
            Log.e(TAG, fnfe.getMessage(), fnfe);
            fail("Test environment not setup correctly");
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    public void testStability() throws IOException, InterruptedException {
        setUpBrowser();

        BufferedReader bufferedReader = getInputStream();
        try {
            loopUrls(bufferedReader, null, true, STABILITY_LOOPCOUNT);
        } catch (FileNotFoundException fnfe) {
            Log.e(TAG, fnfe.getMessage(), fnfe);
            fail("Test environment not setup correctly");
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }
    }

    private void clearCacheUiThread(final WebView webView, final boolean includeDiskFiles) {
        Runnable runner = new Runnable() {

            @Override
            public void run() {
                webView.clearCache(includeDiskFiles);
            }
        };
        getInstrumentation().runOnMainSync(runner);
    }

    private String getUrlUiThread(final WebView webView) {
        WebViewUrlGetter urlGetter = new WebViewUrlGetter(webView);
        getInstrumentation().runOnMainSync(urlGetter);
        return urlGetter.getUrl();
    }

    private class WebViewUrlGetter implements Runnable {

        private WebView mWebView;
        private String mUrl;

        public WebViewUrlGetter(WebView webView) {
            mWebView = webView;
        }

        @Override
        public void run() {
                mUrl = null;
                mUrl = mWebView.getUrl();
        }

        public String getUrl() {
            if (mUrl != null) {
                return mUrl;
            } else
                throw new IllegalStateException("url has not been fetched yet");
        }
    }
}
