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

import android.app.Activity;
import android.app.ActivityThread;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

public class PowerTestActivity extends Activity {

    public static final String LOGTAG = "PowerTestActivity";
    public static final String PARAM_URL = "URL";
    public static final String PARAM_TIMEOUT = "Timeout";
    public static final int RESULT_TIMEOUT = 0xDEAD;
    public static final int MSG_TIMEOUT = 0xC001;
    public static final int MSG_NAVIGATE = 0xC002;
    public static final String MSG_NAV_URL = "url";
    public static final String MSG_NAV_LOGTIME = "logtime";

    private WebView webView;
    private SimpleWebViewClient webViewClient;
    private SimpleChromeClient chromeClient;
    private Handler handler;
    private boolean timeoutFlag;
    private boolean logTime;
    private boolean pageDone;
    private Object pageDoneLock;
    private int pageStartCount;
    private int manualDelay;
    private long startTime;
    private long pageLoadTime;
    private PageDoneRunner pageDoneRunner = new PageDoneRunner();

    public PowerTestActivity() {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));

        LinearLayout contentView = new LinearLayout(this);
        contentView.setOrientation(LinearLayout.VERTICAL);
        setContentView(contentView);
        setTitle("Idle");

        webView = new WebView(this);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
        webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);

        webViewClient = new SimpleWebViewClient();
        chromeClient = new SimpleChromeClient();
        webView.setWebViewClient(webViewClient);
        webView.setWebChromeClient(chromeClient);

        contentView.addView(webView, new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT, 0.0f));

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_TIMEOUT:
                        handleTimeout();
                        return;
                    case MSG_NAVIGATE:
                        manualDelay = msg.arg2;
                        navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1);
                        logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME);
                        return;
                }
            }
        };

        pageDoneLock = new Object();
    }

    public void reset() {
        synchronized (pageDoneLock) {
            pageDone = false;
        }
        timeoutFlag = false;
        pageStartCount = 0;
        chromeClient.resetJsTimeout();
    }

    private void navigate(String url, int timeout) {
        if(url == null) {
            Log.v(LOGTAG, "URL is null, cancelling...");
            finish();
        }
        webView.stopLoading();
        if(logTime) {
            webView.clearCache(true);
        }
        startTime = System.currentTimeMillis();
        Log.v(LOGTAG, "Navigating to URL: " + url);
        webView.loadUrl(url);

        if(timeout != 0) {
            //set a timer with specified timeout (in ms)
            handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
                    timeout);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
        webView.clearCache(true);
        webView.destroy();
    }

    private boolean isPageDone() {
        synchronized (pageDoneLock) {
            return pageDone;
        }
    }

    private void setPageDone(boolean pageDone) {
        synchronized (pageDoneLock) {
            this.pageDone = pageDone;
            pageDoneLock.notifyAll();
        }
    }

    private void handleTimeout() {
        int progress = webView.getProgress();
        webView.stopLoading();
        Log.v(LOGTAG, "Page timeout triggered, progress = " + progress);
        timeoutFlag = true;
        handler.postDelayed(pageDoneRunner, manualDelay);
    }

    public boolean waitUntilDone() {
        validateNotAppThread();
        synchronized (pageDoneLock) {
            while(!isPageDone()) {
                try {
                    pageDoneLock.wait();
                } catch (InterruptedException ie) {
                    //no-op
                }
            }
        }
        return timeoutFlag;
    }

    public Handler getHandler() {
        return handler;
    }

    private final void validateNotAppThread() {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            throw new RuntimeException(
                "This method can not be called from the main application thread");
        }
    }

    public long getPageLoadTime() {
        return pageLoadTime;
    }

    public boolean getPageError() {
        return webViewClient.getPageErrorFlag();
    }

    class SimpleWebViewClient extends WebViewClient {

        private boolean pageErrorFlag = false;

        @Override
        public void onReceivedError(WebView view, int errorCode, String description,
                String failingUrl) {
            pageErrorFlag = true;
            Log.v(LOGTAG, "WebCore error: code=" + errorCode
                    + ", description=" + description
                    + ", url=" + failingUrl);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            pageStartCount++;
            Log.v(LOGTAG, "onPageStarted: " + url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            Log.v(LOGTAG, "onPageFinished: " + url);
            // let handleTimeout take care of finishing the page
            if(!timeoutFlag)
                handler.postDelayed(new WebViewStatusChecker(), 500);
        }

        // return true if the URL is not available or the page is down
        public boolean getPageErrorFlag() {
            return pageErrorFlag;
        }
    }

    class SimpleChromeClient extends WebChromeClient {

        private int timeoutCounter = 0;

        public void resetJsTimeout() {
            timeoutCounter = 0;
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            PowerTestActivity.this.setTitle(title);
        }
    }

    class WebViewStatusChecker implements Runnable {

        private int initialStartCount;

        public WebViewStatusChecker() {
            initialStartCount = pageStartCount;
        }

        public void run() {
            if (initialStartCount == pageStartCount && !isPageDone()) {
                handler.removeMessages(MSG_TIMEOUT);
                webView.stopLoading();
                handler.postDelayed(pageDoneRunner, manualDelay);
            }
        }
    }

    class PageDoneRunner implements Runnable {

        public void run() {
            Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
            pageLoadTime = System.currentTimeMillis() - startTime;
            setPageDone(true);
        }
    }
}
