/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.taobao.weex.ui.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.taobao.weex.utils.WXLogUtils;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

public class WXWebView implements IWebView {

    private Context mContext;
    private String mOrigin;
    private WebView mWebView;
    private ProgressBar mProgressBar;
    private boolean mShowLoading = true;
    private Handler mMessageHandler;
    private static final int POST_MESSAGE = 1;
    private static final String BRIDGE_NAME = "__WEEX_WEB_VIEW_BRIDGE";
    private static final int SDK_VERSION = Build.VERSION.SDK_INT;
    // downgraded by CVE-2012-6636(https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-6636)
    private static final boolean DOWNGRADE_JS_INTERFACE = SDK_VERSION < 17;

    private OnErrorListener mOnErrorListener;
    private OnPageListener mOnPageListener;
    private OnMessageListener mOnMessageListener;

    public WXWebView(Context context, String origin) {
        mContext = context;
        mOrigin = origin;
    }

    @Override
    public View getView() {
        FrameLayout root = new FrameLayout(mContext);
        root.setBackgroundColor(Color.WHITE);

        mWebView = new WebView(mContext);//mContext.getApplicationContext();
        FrameLayout.LayoutParams wvLayoutParams =
                new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                        FrameLayout.LayoutParams.MATCH_PARENT);
        wvLayoutParams.gravity = Gravity.CENTER;
        mWebView.setLayoutParams(wvLayoutParams);
        root.addView(mWebView);
        initWebView(mWebView);

        mProgressBar = new ProgressBar(mContext);
        showProgressBar(false);
        FrameLayout.LayoutParams pLayoutParams =
                new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                        FrameLayout.LayoutParams.WRAP_CONTENT);
        mProgressBar.setLayoutParams(pLayoutParams);
        pLayoutParams.gravity = Gravity.CENTER;
        root.addView(mProgressBar);

        mMessageHandler = new MessageHandler(this);

        return root;
    }

    @Override
    public void destroy() {
        if (getWebView() != null) {
            getWebView().removeAllViews();
            getWebView().destroy();
            mWebView = null;
        }
    }

    @Override
    public void loadUrl(String url) {
        if(getWebView() == null)
            return;
        getWebView().loadUrl(url);
    }

    @Override
    public void loadDataWithBaseURL(String source) {
        if(getWebView() == null)
            return;
        getWebView().loadDataWithBaseURL(mOrigin, source, "text/html", "utf-8", null);
    }

    @Override
    public void reload() {
        if(getWebView() == null)
            return;
        getWebView().reload();
    }

    @Override
    public void goBack() {
        if(getWebView() == null)
            return;
        getWebView().goBack();
    }

    @Override
    public void goForward() {
        if(getWebView() == null)
            return;
        getWebView().goForward();
    }

    @Override
    public void postMessage(Object msg) {
        if (getWebView() == null) return;

        try {
            JSONObject initData = new JSONObject();
            initData.put("type", "message");
            initData.put("data", msg);
            initData.put("origin", mOrigin);
            evaluateJS("javascript:(function () {"
                + "var initData = " + initData.toString() + ";"
                + "try {"
                + "var event = new MessageEvent('message', initData);"
                + "window.dispatchEvent(event);"
                + "} catch (e) {}"
                + "})();");
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    /*@Override
    public void setVisibility(int visibility) {
        if (mRootView != null) {
            mRootView.setVisibility(visibility);
        }
    }*/

    @Override
    public void setShowLoading(boolean shown) {
        mShowLoading = shown;
    }

    @Override
    public void setOnErrorListener(OnErrorListener listener) {
        mOnErrorListener = listener;
    }

    @Override
    public void setOnPageListener(OnPageListener listener) {
        mOnPageListener = listener;
    }

    @Override
    public void setOnMessageListener(OnMessageListener listener) {
        mOnMessageListener = listener;
    }

    private void showProgressBar(boolean shown) {
        if (mShowLoading) {
            mProgressBar.setVisibility(shown ? View.VISIBLE : View.GONE);
        }
    }

    private void showWebView(boolean shown) {
        mWebView.setVisibility(shown ? View.VISIBLE : View.INVISIBLE);
    }

    private @Nullable WebView getWebView() {
        //TODO: remove this, duplicate with getView semantically.
        return mWebView;
    }

    private void initWebView(WebView wv) {
        WebSettings settings = wv.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setAppCacheEnabled(true);
        settings.setUseWideViewPort(true);
        settings.setDomStorageEnabled(true);
        settings.setSupportZoom(false);
        settings.setBuiltInZoomControls(false);
        wv.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                WXLogUtils.v("tag", "onPageOverride " + url);
                return true;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                WXLogUtils.v("tag", "onPageStarted " + url);
                if (mOnPageListener != null) {
                    mOnPageListener.onPageStart(url);
                }
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                WXLogUtils.v("tag", "onPageFinished " + url);
                if (mOnPageListener != null) {
                    mOnPageListener.onPageFinish(url, view.canGoBack(), view.canGoForward());
                }
                if (mOnMessageListener != null) {
                    evaluateJS("javascript:(window.postMessage = function(message, targetOrigin) {"
                        + "if (message == null || !targetOrigin) return;"
                        + (DOWNGRADE_JS_INTERFACE
                        ? "prompt('" + BRIDGE_NAME + "://postMessage?message=' + JSON.stringify(message) + '&targetOrigin=' + targetOrigin)"
                        : BRIDGE_NAME + ".postMessage(JSON.stringify(message), targetOrigin);")
                        + "})");
                }
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                if (mOnErrorListener != null) {
                    //mOnErrorListener.onError("error", "page error code:" + error.getErrorCode() + ", desc:" + error.getDescription() + ", url:" + request.getUrl());
                    mOnErrorListener.onError("error", "page error");
                }
            }

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                super.onReceivedHttpError(view, request, errorResponse);
                if (mOnErrorListener != null) {
                    mOnErrorListener.onError("error", "http error");
                }
            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                super.onReceivedSslError(view, handler, error);
                if (mOnErrorListener != null) {
                    mOnErrorListener.onError("error", "ssl error");
                }
            }
        });
        wv.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                showWebView(newProgress == 100);
                showProgressBar(newProgress != 100);
                WXLogUtils.v("tag", "onPageProgressChanged " + newProgress);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                if (mOnPageListener != null) {
                    mOnPageListener.onReceivedTitle(view.getTitle());
                }
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String text, String defaultValue, JsPromptResult result) {
                Uri uri = Uri.parse(text);
                String scheme = uri.getScheme();
                if (TextUtils.equals(scheme, BRIDGE_NAME)) {
                    if (TextUtils.equals(uri.getAuthority(), "postMessage")) {
                        String message = uri.getQueryParameter("message");
                        String targetOrigin = uri.getQueryParameter("targetOrigin");
                        onMessage(message, targetOrigin);
                        result.confirm("success");
                    } else {
                        result.confirm("fail");
                    }
                    return true;
                }
                return super.onJsPrompt(view, url, text, defaultValue, result);
            }
        });
        if (!DOWNGRADE_JS_INTERFACE) {
            wv.addJavascriptInterface(new Object() {
                @JavascriptInterface
                public void postMessage(String message, String targetOrigin) {
                    onMessage(message, targetOrigin);
                }
            }, BRIDGE_NAME);
        }
    }

    private void onMessage(String message, String targetOrigin) {
        if (message != null && targetOrigin != null && mOnMessageListener != null) {
            try {
                Map<String, Object> initData = new HashMap<>();
                initData.put("data", JSON.parse(message));
                initData.put("origin", targetOrigin);
                initData.put("type", "message");
                Message threadMessage = new Message();
                threadMessage.what = POST_MESSAGE;
                threadMessage.obj = initData;
                mMessageHandler.sendMessage(threadMessage);
            } catch (JSONException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void evaluateJS(String jsStr) {
        if (SDK_VERSION < 19) {
            mWebView.loadUrl(jsStr);
        } else {
            mWebView.evaluateJavascript(jsStr, null);
        }
    }

    private static class MessageHandler extends Handler {
        private final WeakReference<WXWebView> mWv;

        private MessageHandler(WXWebView wv) {
            mWv = new WeakReference<>(wv);
        }

        @Override
        @SuppressWarnings("unchecked")
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case POST_MESSAGE:
                    if (mWv.get() != null && mWv.get().mOnMessageListener != null) {
                        mWv.get().mOnMessageListener.onMessage((Map<String, Object>) msg.obj);
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
