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

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ViewGroup;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;

public class TestShellActivity extends Activity implements LayoutTestController {

    static enum DumpDataType {DUMP_AS_TEXT, EXT_REPR, NO_OP}

    public class AsyncHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == MSG_TIMEOUT) {
                mTimedOut = true;
                if(mCallback != null)
                    mCallback.timedOut(mWebView.getUrl());
                requestWebKitData();
                return;
            } else if (msg.what == MSG_WEBKIT_DATA) {
                TestShellActivity.this.dump(mTimedOut, (String)msg.obj);
                return;
            }

            super.handleMessage(msg);
        }
    }

    public void requestWebKitData() {
        Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA);

        if (mRequestedWebKitData)
            throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl());

        mRequestedWebKitData = true;
        switch (mDumpDataType) {
            case DUMP_AS_TEXT:
                mWebView.documentAsText(callback);
                break;
            case EXT_REPR:
                mWebView.externalRepresentation(callback);
                break;
            default:
                finished();
                break;
        }
    }

    public void clearCache() {
      mWebView.freeMemory();
    }

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

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

        mWebView = new WebView(this);
        mEventSender = new WebViewEventSender(mWebView);
        mCallbackProxy = new CallbackProxy(mEventSender, this);

        setupWebViewForLayoutTests(mWebView, mCallbackProxy);

        contentView.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT, 0.0f));

        mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);

        mHandler = new AsyncHandler();

        Intent intent = getIntent();
        if (intent != null) {
            executeIntent(intent);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        executeIntent(intent);
    }

    private void executeIntent(Intent intent) {
        resetTestStatus();
        if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
            return;
        }

        mTestUrl = intent.getStringExtra(TEST_URL);
        if (mTestUrl == null) {
            mUiAutoTestPath = intent.getStringExtra(UI_AUTO_TEST);
            if(mUiAutoTestPath != null) {
                beginUiAutoTest();
            }
            return;
        }

        mResultFile = intent.getStringExtra(RESULT_FILE);
        mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0);

        Log.v(LOGTAG, "  Loading " + mTestUrl);
        mWebView.loadUrl(mTestUrl);

        if (mTimeoutInMillis > 0) {
            // Create a timeout timer
            Message m = mHandler.obtainMessage(MSG_TIMEOUT);
            mHandler.sendMessageDelayed(m, mTimeoutInMillis);
        }
    }

    private void beginUiAutoTest() {
        try {
            mTestListReader = new BufferedReader(
                    new FileReader(mUiAutoTestPath));
        } catch (IOException ioe) {
            Log.e(LOGTAG, "Failed to open test list for read.", ioe);
            finishUiAutoTest();
            return;
        }
        moveToNextTest();
    }

    private void finishUiAutoTest() {
        try {
            if(mTestListReader != null)
                mTestListReader.close();
        } catch (IOException ioe) {
            Log.w(LOGTAG, "Failed to close test list file.", ioe);
        }
        finished();
    }

    private void moveToNextTest() {
        String url = null;
        try {
            url = mTestListReader.readLine();
        } catch (IOException ioe) {
            Log.e(LOGTAG, "Failed to read next test.", ioe);
            finishUiAutoTest();
            return;
        }
        if (url == null) {
            mUiAutoTestPath = null;
            finishUiAutoTest();
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("All tests finished. Exit?")
                   .setCancelable(false)
                   .setPositiveButton("Yes", new OnClickListener(){
                       public void onClick(DialogInterface dialog, int which) {
                           TestShellActivity.this.finish();
                       }
                   })
                   .setNegativeButton("No", new OnClickListener(){
                       public void onClick(DialogInterface dialog, int which) {
                           dialog.cancel();
                       }
                   });
            builder.create().show();
            return;
        }
        url = "file://" + url;
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.putExtra(TestShellActivity.TEST_URL, url);
        intent.putExtra(TIMEOUT_IN_MILLIS, 10000);
        executeIntent(intent);
    }

    @Override
    protected void onStop() {
        super.onStop();
        mWebView.stopLoading();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mWebView.destroy();
        mWebView = null;
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        Log.e(LOGTAG, "Low memory, clearing caches");
        mWebView.freeMemory();
    }

    // Dump the page
    public void dump(boolean timeout, String webkitData) {
        if (mResultFile == null || mResultFile.length() == 0) {
            finished();
            return;
        }

        try {
            File parentDir = new File(mResultFile).getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }

            FileOutputStream os = new FileOutputStream(mResultFile);
            if (timeout) {
                Log.w("Layout test: Timeout", mResultFile);
                os.write(TIMEOUT_STR.getBytes());
                os.write('\n');
            }
            if (mDumpTitleChanges)
                os.write(mTitleChanges.toString().getBytes());
            if (mDialogStrings != null)
                os.write(mDialogStrings.toString().getBytes());
            mDialogStrings = null;
            if (mDatabaseCallbackStrings != null)
                os.write(mDatabaseCallbackStrings.toString().getBytes());
            mDatabaseCallbackStrings = null;
            if (mConsoleMessages != null)
                os.write(mConsoleMessages.toString().getBytes());
            mConsoleMessages = null;
            if (webkitData != null)
                os.write(webkitData.getBytes());
            os.flush();
            os.close();
        } catch (IOException ex) {
            Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage());
        }

        finished();
    }

    public void setCallback(TestShellCallback callback) {
        mCallback = callback;
    }

    public void finished() {
        if (mUiAutoTestPath != null) {
            //don't really finish here
            moveToNextTest();
        } else {
            if (mCallback != null) {
                mCallback.finished();
            }
        }
    }

    public void setDefaultDumpDataType(DumpDataType defaultDumpDataType) {
        mDefaultDumpDataType = defaultDumpDataType;
    }

    // .......................................
    // LayoutTestController Functions
    public void dumpAsText() {
        mDumpDataType = DumpDataType.DUMP_AS_TEXT;
        if (mWebView != null) {
            String url = mWebView.getUrl();
            Log.v(LOGTAG, "dumpAsText called: "+url);
        }
    }

    public void waitUntilDone() {
        mWaitUntilDone = true;
        String url = mWebView.getUrl();
        Log.v(LOGTAG, "waitUntilDone called: " + url);
    }

    public void notifyDone() {
        String url = mWebView.getUrl();
        Log.v(LOGTAG, "notifyDone called: " + url);
        if (mWaitUntilDone) {
            mWaitUntilDone = false;
            mChromeClient.onProgressChanged(mWebView, 100);
        }
    }

    public void display() {
        mWebView.invalidate();
    }

    public void clearBackForwardList() {
        mWebView.clearHistory();

    }

    public void dumpBackForwardList() {
        //printf("\n============== Back Forward List ==============\n");
        // mWebHistory
        //printf("===============================================\n");

    }

    public void dumpChildFrameScrollPositions() {
        // TODO Auto-generated method stub

    }

    public void dumpEditingCallbacks() {
        // TODO Auto-generated method stub

    }

    public void dumpSelectionRect() {
        // TODO Auto-generated method stub

    }

    public void dumpTitleChanges() {
        if (!mDumpTitleChanges) {
            mTitleChanges = new StringBuffer();
        }
        mDumpTitleChanges = true;
    }

    public void keepWebHistory() {
        if (!mKeepWebHistory) {
            mWebHistory = new Vector();
        }
        mKeepWebHistory = true;
    }

    public void queueBackNavigation(int howfar) {
        // TODO Auto-generated method stub

    }

    public void queueForwardNavigation(int howfar) {
        // TODO Auto-generated method stub

    }

    public void queueLoad(String Url, String frameTarget) {
        // TODO Auto-generated method stub

    }

    public void queueReload() {
        mWebView.reload();
    }

    public void queueScript(String scriptToRunInCurrentContext) {
        mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext);
    }

    public void repaintSweepHorizontally() {
        // TODO Auto-generated method stub

    }

    public void setAcceptsEditing(boolean b) {
        // TODO Auto-generated method stub

    }

    public void setMainFrameIsFirstResponder(boolean b) {
        // TODO Auto-generated method stub

    }

    public void setWindowIsKey(boolean b) {
        // This is meant to show/hide the window. The best I can find
        // is setEnabled()
        mWebView.setEnabled(b);
    }

    public void testRepaint() {
        mWebView.invalidate();
    }

    public void dumpDatabaseCallbacks() {
        Log.v(LOGTAG, "dumpDatabaseCallbacks called.");
        mDumpDatabaseCallbacks = true;
    }

    public void setCanOpenWindows() {
        Log.v(LOGTAG, "setCanOpenWindows called.");
        mCanOpenWindows = true;
    }

    private final WebViewClient mViewClient = new WebViewClient(){
        @Override
        public void onPageFinished(WebView view, String url) {
            Log.v(LOGTAG, "onPageFinished, url=" + url);
            super.onPageFinished(view, url);
        }

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

        @Override
        public void onReceivedError(WebView view, int errorCode, String description,
                String failingUrl) {
            Log.v(LOGTAG, "onReceivedError, errorCode=" + errorCode
                    + ", desc=" + description + ", url=" + failingUrl);
            super.onReceivedError(view, errorCode, description, failingUrl);
        }

        @Override
        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
                String host, String realm) {
            handler.cancel();
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                SslError error) {
            handler.proceed();
        }
    };


    private final WebChromeClient mChromeClient = new WebChromeClient() {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
                if (!mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) {
                    String url = mWebView.getUrl();
                    Log.v(LOGTAG, "Finished: "+ url);
                    mHandler.removeMessages(MSG_TIMEOUT);
                    requestWebKitData();
                } else {
                    String url = mWebView.getUrl();
                    if (mTimedOut) {
                        Log.v(LOGTAG, "Timed out before finishing: " + url);
                    } else if (mWaitUntilDone) {
                        Log.v(LOGTAG, "Waiting for notifyDone: " + url);
                    } else if (mRequestedWebKitData) {
                        Log.v(LOGTAG, "Requested webkit data ready: " + url);
                    }
                }
            }
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            if (title.length() > 30)
                title = "..."+title.substring(title.length()-30);
            setTitle(title);
            if (mDumpTitleChanges) {
                mTitleChanges.append("TITLE CHANGED: ");
                mTitleChanges.append(title);
                mTitleChanges.append("\n");
            }
        }

        @Override
        public boolean onJsAlert(WebView view, String url, String message,
                JsResult result) {
            if (mDialogStrings == null) {
                mDialogStrings = new StringBuffer();
            }
            mDialogStrings.append("ALERT: ");
            mDialogStrings.append(message);
            mDialogStrings.append('\n');
            result.confirm();
            return true;
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message,
                JsResult result) {
            if (mDialogStrings == null) {
                mDialogStrings = new StringBuffer();
            }
            mDialogStrings.append("CONFIRM: ");
            mDialogStrings.append(message);
            mDialogStrings.append('\n');
            result.confirm();
            return true;
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message,
                String defaultValue, JsPromptResult result) {
            if (mDialogStrings == null) {
                mDialogStrings = new StringBuffer();
            }
            mDialogStrings.append("PROMPT: ");
            mDialogStrings.append(message);
            mDialogStrings.append(", default text: ");
            mDialogStrings.append(defaultValue);
            mDialogStrings.append('\n');
            result.confirm();
            return true;
        }

        @Override
        public boolean onJsTimeout() {
            Log.v(LOGTAG, "JavaScript timeout");
            return false;
        }

        @Override
        public void onExceededDatabaseQuota(String url_str,
                String databaseIdentifier, long currentQuota, long totalUsedQuota,
                WebStorage.QuotaUpdater callback) {
            if (mDumpDatabaseCallbacks) {
                if (mDatabaseCallbackStrings == null) {
                    mDatabaseCallbackStrings = new StringBuffer();
                }

                String protocol = "";
                String host = "";
                int port = 0;

                try {
                    URL url = new URL(url_str);
                    protocol = url.getProtocol();
                    host = url.getHost();
                    if (url.getPort() > -1) {
                        port = url.getPort();
                    }
                } catch (MalformedURLException e) {}

                String databaseCallbackString =
                        "UI DELEGATE DATABASE CALLBACK: " +
                        "exceededDatabaseQuotaForSecurityOrigin:{" + protocol +
                        ", " + host + ", " + port + "} database:" +
                        databaseIdentifier + "\n";
                Log.v(LOGTAG, "LOG: "+databaseCallbackString);
                mDatabaseCallbackStrings.append(databaseCallbackString);
            }
            // Give 5MB more quota.
            callback.updateQuota(currentQuota + 1024 * 1024 * 5);
        }

        @Override
        public void addMessageToConsole(String message, int lineNumber,
                String sourceID) {
            if (mConsoleMessages == null) {
                mConsoleMessages = new StringBuffer();
            }
            String consoleMessage = "CONSOLE MESSAGE: line "
                    + lineNumber +": "+ message +"\n";
            mConsoleMessages.append(consoleMessage);
            Log.v(LOGTAG, "LOG: "+consoleMessage);
        }

        @Override
        public boolean onCreateWindow(WebView view, boolean dialog,
                boolean userGesture, Message resultMsg) {
            if (!mCanOpenWindows) {
                return false;
            }

            // We never display the new window, just create the view and
            // allow it's content to execute and be recorded by the test
            // runner.

            WebView newWindowView = new WebView(TestShellActivity.this);
            setupWebViewForLayoutTests(newWindowView, mCallbackProxy);
            WebView.WebViewTransport transport =
                    (WebView.WebViewTransport) resultMsg.obj;
            transport.setWebView(newWindowView);
            resultMsg.sendToTarget();
            return true;
        }
    };

    private void resetTestStatus() {
        mWaitUntilDone = false;
        mDumpDataType = mDefaultDumpDataType;
        mTimedOut = false;
        mDumpTitleChanges = false;
        mRequestedWebKitData = false;
        mDumpDatabaseCallbacks = false;
        mCanOpenWindows = false;
        mEventSender.resetMouse();
    }

    private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) {
        if (webview == null) {
            return;
        }

        WebSettings settings = webview.getSettings();
        settings.setAppCacheEnabled(true);
        settings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
        settings.setAppCacheMaxSize(Long.MAX_VALUE);
        settings.setJavaScriptEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setSupportMultipleWindows(true);
        settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
        settings.setDatabaseEnabled(true);
        settings.setDatabasePath(getDir("databases",0).getAbsolutePath());
        settings.setDomStorageEnabled(true);
        settings.setWorkersEnabled(true);

        webview.addJavascriptInterface(callbackProxy, "layoutTestController");
        webview.addJavascriptInterface(callbackProxy, "eventSender");

        webview.setWebChromeClient(mChromeClient);
        webview.setWebViewClient(mViewClient);
    }

    private WebView mWebView;
    private WebViewEventSender mEventSender;
    private AsyncHandler mHandler;
    private TestShellCallback mCallback;

    private CallbackProxy mCallbackProxy;

    private String mTestUrl;
    private String mResultFile;
    private int mTimeoutInMillis;
    private String mUiAutoTestPath;
    private BufferedReader mTestListReader;

    // States
    private boolean mTimedOut;
    private boolean mRequestedWebKitData;
    private boolean mFinishedRunning;

    // Layout test controller variables.
    private DumpDataType mDumpDataType;
    private DumpDataType mDefaultDumpDataType = DumpDataType.EXT_REPR;
    private boolean mWaitUntilDone;
    private boolean mDumpTitleChanges;
    private StringBuffer mTitleChanges;
    private StringBuffer mDialogStrings;
    private boolean mKeepWebHistory;
    private Vector mWebHistory;
    private boolean mDumpDatabaseCallbacks;
    private StringBuffer mDatabaseCallbackStrings;
    private StringBuffer mConsoleMessages;
    private boolean mCanOpenWindows;

    static final String TIMEOUT_STR = "**Test timeout";

    static final int MSG_TIMEOUT = 0;
    static final int MSG_WEBKIT_DATA = 1;

    static final String LOGTAG="TestShell";

    static final String TEST_URL = "TestUrl";
    static final String RESULT_FILE = "ResultFile";
    static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis";
    static final String UI_AUTO_TEST = "UiAutoTest";
}
