/*
 * Copyright (c) 2016 Oracle and/or its affiliates.  All rights reserved.
 *
 * This software is dual-licensed to you under the MIT License (MIT) and
 * the Universal Permissive License (UPL).  See the LICENSE file in the root
 * directory for license terms.  You may choose either license, or both.
 */

package com.oracle.iot.sample.enterpriseclientsample;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import com.oracle.iot.sample.R;

import com.oracle.iot.client.trust.TrustedAssetsManager;
import com.oracle.iot.sample.SelectProvisioningActivity;

import java.net.URL;

import oracle.iot.client.enterprise.EnterpriseClient;
import oracle.iot.client.enterprise.UserAuthenticationException;

/**
 * A login screen that offers login via email/password.
 */
public class SSOLoginActivity extends Activity {

    String applicationName;
    public EnterpriseClient ecl = null;

    Button btnLoadIotApp;
    EditText editTxtIoTApp;
    WebView loginWebView;
    TrustedAssetsManager tam;

    public final static String TAG = "IOT_ERROR";
    public final static String IOT_APP_URL = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ssologin);
        btnLoadIotApp = (Button)findViewById(R.id.btnScreen1Next);
        btnLoadIotApp.setVisibility(View.INVISIBLE);
        editTxtIoTApp = (EditText) findViewById(R.id.editAppName);
        editTxtIoTApp.setVisibility(View.INVISIBLE);

        loginWebView =(WebView)findViewById(R.id.webView);
        loginWebView.setWebViewClient(new MyBrowser());
        loginWebView.getSettings().setLoadsImagesAutomatically(true);
        loginWebView.getSettings().setJavaScriptEnabled(true);
        loginWebView.getSettings().setDomStorageEnabled(true);
        loginWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        while(!loadLoginPage()){
        }
    }

    private boolean loadLoginPage(){
        try {
            tam = EnterpriseClientUtil.getInstance(this).getTam();
            URL serverURL = new URL("https", tam.getServerHost(), tam.getServerPort(), "ui");
            loginWebView.loadUrl(serverURL.toString());
        }catch(java.net.MalformedURLException e){
            e.printStackTrace();
            showAlert("Error", "Could not contact the server. Please re-provision with correct host name and try again");
            return false;
        }
        return true;
    }

    private void showAlert(String title, String message){
        AlertDialog alertDialog = new AlertDialog.Builder(SSOLoginActivity.this).create();
        alertDialog.setTitle(title);
        alertDialog.setMessage(message);
        alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        alertDialog.show();
    }

    private class MyBrowser extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url != null && url.equals(IOT_APP_URL)) {

                view.setVisibility(View.GONE);

                btnLoadIotApp.setVisibility(View.VISIBLE);
                editTxtIoTApp.setVisibility(View.VISIBLE);

                return false;
            } else {
                view.loadUrl(url);
                return true;
            }
        }

        @Override
        public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
			final AlertDialog.Builder builder = new AlertDialog.Builder(SSOLoginActivity.this);
			String msg = "A generic SSL error occurred";
			switch (error.getPrimaryError()) {
				case SslError.SSL_DATE_INVALID:
					msg = "The date of the certificate is invalid\n";
					break;
				case SslError.SSL_EXPIRED:
					msg = "The certificate has expired\n";
					break;
				case SslError.SSL_IDMISMATCH:
					msg = "The certificate Hostname mismatch\n";
					break;
				case SslError.SSL_NOTYETVALID:
					msg = "The certificate is not yet valid\n";
					break;
				case SslError.SSL_UNTRUSTED:
					msg = "The certificate authority is not trusted\n";
					break;
			}
			msg += error.toString();
			msg += "\nDo you want to continue anyway?";

			builder.setTitle("SSL Error");
			builder.setMessage(msg);
			builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					handler.proceed();
				}
			});
			builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					handler.cancel();
				}
			});
			final AlertDialog dialog = builder.create();
			dialog.show();
        }

        @Override
        public void onPageFinished(WebView view, String url){
            super.onPageFinished(view, url);
            final String cookie = CookieManager.getInstance().getCookie(url);
			// TODO I found 2 type of cookies, that show authentification. Need to clarify which will be common
            if(cookie != null && (cookie.contains("OAMAuthnCookie") || cookie.contains("AUTHCOOKIE_IOTSESSIONID"))) {
                view.setVisibility(View.GONE);

                btnLoadIotApp.setVisibility(View.VISIBLE);
                editTxtIoTApp.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon){
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error){
            super.onReceivedError(view, request, error);
        }
    }

    public void sendDeviceModels(View v) {
        // create intent and send application name to next activity
        applicationName = ((EditText) findViewById(R.id.editAppName)).getText().toString();

        new ECLOperation().execute(this);
    }

    @Override
    public void onBackPressed() {
        Intent intent = new Intent(SSOLoginActivity.this, SelectProvisioningActivity.class);
        intent.putExtra("RESET", true);
        startActivity(intent);
        finish();
    }

    private class ECLOperation extends AsyncTask<Context, Void, EnterpriseClient> {
        private Context context;
        private boolean reloadActivity = false;
        private UserAuthenticationException error = null;

        @Override
        protected EnterpriseClient doInBackground(Context... params)  {
            context = params[0];

            try {
                EnterpriseClientUtil clientUtil = EnterpriseClientUtil.getInstance(null);
                if(clientUtil.getECL() == null)
                    clientUtil.initializeECL(applicationName,context);
                ecl= clientUtil.getECL();
            } catch(UserAuthenticationException uae) {
                this.reloadActivity = true;
                Log.e(TAG, uae.getMessage());
            }

            return ecl;
        }

        @Override
        protected void onPostExecute(EnterpriseClient ecl) {
            Intent intent = null;
            if(this.reloadActivity == true ) {
                intent = new Intent(context, SelectProvisioningActivity.class);
                intent.putExtra("RESET", true);
                startActivity(intent);
                finish();
            }else {
                EnterpriseClientUtil.getInstance(null).setAppName(SSOLoginActivity.this.applicationName);
                intent = new Intent(context, DeviceModelListActivity.class);
                startActivity(intent);
                finish();
            }
        }
    }
}

