package kz.arta.synergy.workflow.mobile.android.works.activities.completion.process;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.devspark.appmsg.AppMsg;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.X509Certificate;

import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.common.ActivityConst;
import kz.arta.synergy.workflow.mobile.android.common.SettingsConst;
import kz.arta.synergy.workflow.mobile.android.common.components.OpenFileDialog;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.utils.Utils;
import kz.arta.synergy.workflow.mobile.android.works.manager.completion.SignManager;

/**
 * Created by neox on 16.02.16.
 * Экран ввода пароля для сертификата
 */
public class CertPasswordActivity extends Activity {

    /**
     * Пользователь
     */
    private Person person;

    /**
     * Активити
     */
    private Activity activity;

    /**
     * Компонент для ввода пароля
     */
    private EditText password;

    /**
     * Файл сертификата лежащего на устройстве
     */
    private File file;

    /**
     * Сертификат
     */
    private X509Certificate certificate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.cert_password_activity);

        ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }

        activity = this;

        person = (Person) getIntent().getSerializableExtra(ActivityConst.PERSON);

        // имя файла
        final TextView fileName = (TextView) findViewById(R.id.cert_password_activity_file_name);

        // компонент для ввода пароля
        password = (EditText) findViewById(R.id.cert_password_activity_password);

        // кнопка "Подписать"
        final Button signButton = (Button) findViewById(R.id.cert_password_activity_sign_button);
        signButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TextUtils.isEmpty(password.getText())) {
                    AppMsg.makeText(activity, getString(R.string.enter_password), AppMsg.STYLE_ALERT).show();
                    return;
                }
                SignManager signManager = new SignManager();
                signManager.setFilePath(file.getPath());
                signManager.setPassword(password.getText().toString());
                // валидация сертификата на клиенте
                int validPassword = signManager.validPassword();
                if (validPassword == SignManager.OK) {
                    certificate = signManager.getCert();
                    if (certificate != null) {
                        // валидация сертификата на сервере
                        new ValidateCert().execute();
                    } else {
                        AppMsg.makeText(activity, getString(R.string.error_to_parse_cert), AppMsg.STYLE_ALERT).show();
                    }
                } else if (validPassword == SignManager.INCORRECT_PASSWORD) {
                    AppMsg.makeText(activity, getString(R.string.incorrect_password), AppMsg.STYLE_ALERT).show();
                } else if (validPassword == SignManager.INCORRECT_ALG) {
                    AppMsg.makeText(activity, getString(R.string.unknown_cert_alg), AppMsg.STYLE_ALERT).show();
                }
            }
        });

        // кнопка "Изменить ЭЦП"
        final Button changeEdsButton = (Button) findViewById(R.id.cert_password_activity_change_eds_button);
        changeEdsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final OpenFileDialog fileDialog = new OpenFileDialog(activity);
                fileDialog.setCancelable(true);
                fileDialog.setFilter(ProcessConst.FILTER);
                fileDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        finish();
                    }
                });
                fileDialog.setOpenDialogListener(new OpenFileDialog.OpenDialogListener() {
                    @Override
                    public void OnSelectedFile(String filePath) {
                        file = new File(filePath);
                        fileName.setText(file.getName());
                        password.setText("");
                    }
                });
                fileDialog.setButtonPressedListener(new OpenFileDialog.OnButtonPressedListener() {
                    @Override
                    public void onOkPressed() {
                        AppMsg.makeText(activity, getString(R.string.file_not_selected), AppMsg.STYLE_ALERT).show();
                    }

                    @Override
                    public void onCancelPressed() {
                        finish();
                    }
                });
                fileDialog.setCancelable(true);
                fileDialog.show().getWindow().setLayout(Utils.dpToPx(ProcessConst.DIALOG_WIDTH, activity),
                        Utils.dpToPx(ProcessConst.DIALOG_HEIGHT, activity));
            }
        });

        // путь до сертификата
        String path = getIntent().getStringExtra(ProcessConst.CERT_PATH);

        if (path == null) {
            AppMsg.makeText(activity, getString(R.string.cert_path_not_found), AppMsg.STYLE_ALERT).show();
            return;
        }

        file = new File(path);

        if (!file.exists()) {
            AppMsg.makeText(activity, getString(R.string.file_not_found), AppMsg.STYLE_ALERT).show();
            return;
        }

        fileName.setText(file.getName());
    }

    /**
     * Класс используется для валидации сертификата на сервере
     */
    class ValidateCert extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            try {
                String cert = Base64.encodeToString(certificate.getEncoded(), Base64.NO_WRAP);
                String postParams = "uuid=" + person.getUuid() + "&pemCer=" + URLEncoder.encode(cert, "utf-8") + "&edsInfo=Arta";
                HttpURLConnection con = (HttpURLConnection) new URL(person.getHost() + "rest/sign/verificationkey").openConnection();
                con.setRequestMethod("POST");
                con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
                con.setDoOutput(true);
                OutputStream os = con.getOutputStream();
                os.write(postParams.getBytes());
                os.flush();
                os.close();
                BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                return response.toString();
            } catch (Exception exc) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(String result) {
            if (result == null) {
                AppMsg.makeText(activity, getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
                return;
            }
            if (result.contains("::::")) {
                SharedPreferences.Editor editor = getSharedPreferences(SettingsConst.DEFAULT_NAME_SETTINGS, Context.MODE_PRIVATE).edit();
                editor.putString(ProcessConst.CERT_PATH, result);
                editor.apply();
                Intent intent = new Intent();
                intent.putExtra(ProcessConst.CERT_ID, result.substring(0, result.indexOf("::::")));
                intent.putExtra(ProcessConst.CERT_PATH, file.getPath());
                intent.putExtra(ProcessConst.CERT_PASSWORD, password.getText().toString());
                setResult(RESULT_OK, intent);
                finish();
            } else if (result.equals(ProcessConst.CERT_END)) {
                AppMsg.makeText(activity, getString(R.string.cert_end_error), AppMsg.STYLE_ALERT).show();
            } else if (result.equals(ProcessConst.CERT_REVOKED)) {
                AppMsg.makeText(activity, getString(R.string.cert_revoked_error), AppMsg.STYLE_ALERT).show();
            } else if (result.equals(ProcessConst.DISTRIBUTION_CENTER_NOT_FOUND)) {
                AppMsg.makeText(activity, getString(R.string.error_to_parse_cert), AppMsg.STYLE_ALERT).show();
            } else if (result.equals(ProcessConst.ERROR_PARSE_CERT)) {
                AppMsg.makeText(activity, getString(R.string.error_to_parse_cert), AppMsg.STYLE_ALERT).show();
            } else if (result.equals(ProcessConst.ERROR_SAVE_CERT)) {
                AppMsg.makeText(activity, getString(R.string.unknown_cert_alg), AppMsg.STYLE_ALERT).show();
            }
            super.onPostExecute(result);
        }
    }
}
