/*
 * Copyright (c) 2012-2016 Arne Schwabe
 * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
 */

package de.blinkt.openvpn.fragments;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import android.widget.AdapterView.OnItemSelectedListener;
import de.blinkt.openvpn.R;
import de.blinkt.openvpn.R.id;
import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.views.FileSelectLayout;

public class Settings_Basic extends KeyChainSettingsFragment implements OnItemSelectedListener, FileSelectLayout.FileSelectCallback, CompoundButton.OnCheckedChangeListener {
    private static final int CHOOSE_FILE_OFFSET = 1000;

    private FileSelectLayout mClientCert;
    private FileSelectLayout mCaCert;
    private FileSelectLayout mClientKey;
    private CheckBox mUseLzo;
    private CheckBox mUseLegacyProvider;
    private Spinner mType;
    private Spinner mCompatMode;
    private FileSelectLayout mpkcs12;
    private FileSelectLayout mCrlFile;
    private TextView mPKCS12Password;
    private EditText mUserName;
    private EditText mPassword;
    private View mView;
    private EditText mProfileName;
    private EditText mKeyPassword;
    private CheckBox mEnablePeerFingerprint;
    private EditText mPeerFingerprints;

    private SparseArray<FileSelectLayout> fileselects = new SparseArray<>();
    private Spinner mAuthRetry;


    private void addFileSelectLayout(FileSelectLayout fsl, Utils.FileType type) {
        int i = fileselects.size() + CHOOSE_FILE_OFFSET;
        fileselects.put(i, fsl);
        fsl.setCaller(this, i, type);
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


        mView = inflater.inflate(R.layout.basic_settings, container, false);

        mProfileName = mView.findViewById(id.profilename);
        mClientCert = mView.findViewById(id.certselect);
        mClientKey = mView.findViewById(id.keyselect);
        mCaCert = mView.findViewById(id.caselect);
        mpkcs12 = mView.findViewById(id.pkcs12select);
        mCrlFile = mView.findViewById(id.crlfile);
        mUseLzo = mView.findViewById(id.lzo);
        mUseLegacyProvider = mView.findViewById(R.id.legacyprovider);
        mType = mView.findViewById(id.type);
        mCompatMode = mView.findViewById(id.compatmode);
        mPKCS12Password = mView.findViewById(id.pkcs12password);
        mEnablePeerFingerprint = mView.findViewById(id.enable_peer_fingerprint);
        mPeerFingerprints = mView.findViewById(id.peer_fingerprint);

        mUserName = mView.findViewById(id.auth_username);
        mPassword = mView.findViewById(id.auth_password);
        mKeyPassword = mView.findViewById(id.key_password);
        mAuthRetry = mView.findViewById(id.auth_retry);

        addFileSelectLayout(mCaCert, Utils.FileType.CA_CERTIFICATE);
        addFileSelectLayout(mClientCert, Utils.FileType.CLIENT_CERTIFICATE);
        addFileSelectLayout(mClientKey, Utils.FileType.KEYFILE);
        addFileSelectLayout(mpkcs12, Utils.FileType.PKCS12);
        addFileSelectLayout(mCrlFile, Utils.FileType.CRL_FILE);
        mCaCert.setShowClear();
        mCrlFile.setShowClear();

        mType.setOnItemSelectedListener(this);
        mAuthRetry.setOnItemSelectedListener(this);
        mEnablePeerFingerprint.setOnCheckedChangeListener(this);

        initKeychainViews(mView);

        return mView;
    }


    @Override
    public void onActivityResult(int request, int result, Intent data) {
        super.onActivityResult(request, result, data);
        if (result == Activity.RESULT_OK && request >= CHOOSE_FILE_OFFSET) {
            FileSelectLayout fsl = fileselects.get(request);
            fsl.parseResponse(data, getActivity());

            savePreferences();

            // Private key files may result in showing/hiding the private key password dialog
            if (fsl == mClientKey) {
                changeType(mType.getSelectedItemPosition());
            }
        }

    }


    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if (parent == mType) {
            changeType(position);
        }
    }


    private void changeType(int type) {
        // hide everything
        mView.findViewById(R.id.pkcs12).setVisibility(View.GONE);
        mView.findViewById(R.id.certs).setVisibility(View.GONE);
        mView.findViewById(R.id.statickeys).setVisibility(View.GONE);
        mView.findViewById(R.id.keystore).setVisibility(View.GONE);
        mView.findViewById(R.id.cacert).setVisibility(View.GONE);
        ((FileSelectLayout) mView.findViewById(R.id.caselect)).setClearable(false);
        mView.findViewById(R.id.userpassword).setVisibility(View.GONE);
        mView.findViewById(R.id.key_password_layout).setVisibility(View.GONE);
        mView.findViewById(R.id.external_auth).setVisibility(View.GONE);
        mView.findViewById(R.id.crlfile).setVisibility(View.VISIBLE);



        // Fall through are by design
        switch (type) {
            case VpnProfile.TYPE_USERPASS_CERTIFICATES:
                mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
            case VpnProfile.TYPE_CERTIFICATES:
                mView.findViewById(R.id.certs).setVisibility(View.VISIBLE);
                mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
                if (mProfile.requireTLSKeyPassword())
                    mView.findViewById(R.id.key_password_layout).setVisibility(View.VISIBLE);
                break;

            case VpnProfile.TYPE_USERPASS_PKCS12:
                mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
            case VpnProfile.TYPE_PKCS12:
                mView.findViewById(R.id.pkcs12).setVisibility(View.VISIBLE);
                mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
                ((FileSelectLayout) mView.findViewById(R.id.caselect)).setClearable(true);
                break;

            case VpnProfile.TYPE_STATICKEYS:
                mView.findViewById(R.id.statickeys).setVisibility(View.VISIBLE);
                mView.findViewById(R.id.crlfile).setVisibility(View.GONE);
                break;

            case VpnProfile.TYPE_USERPASS_KEYSTORE:
                mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
            case VpnProfile.TYPE_KEYSTORE:
                mView.findViewById(R.id.keystore).setVisibility(View.VISIBLE);
                mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
                ((FileSelectLayout) mView.findViewById(R.id.caselect)).setClearable(true);
                break;

            case VpnProfile.TYPE_USERPASS:
                mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
                mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
                break;
            case VpnProfile.TYPE_EXTERNAL_APP:
                mView.findViewById(R.id.external_auth).setVisibility(View.VISIBLE);
                break;
        }


    }

    protected void loadPreferences() {
        super.loadPreferences();
        mProfileName.setText(mProfile.mName);
        mClientCert.setData(mProfile.mClientCertFilename, getActivity());
        mClientKey.setData(mProfile.mClientKeyFilename, getActivity());
        mCaCert.setData(mProfile.mCaFilename, getActivity());
        mCrlFile.setData(mProfile.mCrlFilename, getActivity());

        mUseLzo.setChecked(mProfile.mUseLzo);
        mUseLegacyProvider.setChecked(mProfile.mUseLegacyProvider);
        mType.setSelection(mProfile.mAuthenticationType);
        mCompatMode.setSelection(Utils.mapCompatVer(mProfile.mCompatMode));
        mpkcs12.setData(mProfile.mPKCS12Filename, getActivity());
        mPKCS12Password.setText(mProfile.mPKCS12Password);
        mUserName.setText(mProfile.mUsername);
        mPassword.setText(mProfile.mPassword);
        mKeyPassword.setText(mProfile.mKeyPassword);
        mAuthRetry.setSelection(mProfile.mAuthRetry);
        mEnablePeerFingerprint.setChecked(mProfile.mCheckPeerFingerprint);
        mPeerFingerprints.setText(mProfile.mPeerFingerPrints);
    }

    protected void savePreferences() {
        super.savePreferences();
        mProfile.mName = mProfileName.getText().toString();
        mProfile.mCaFilename = mCaCert.getData();
        mProfile.mClientCertFilename = mClientCert.getData();
        mProfile.mClientKeyFilename = mClientKey.getData();
        mProfile.mCrlFilename = mCrlFile.getData();

        mProfile.mUseLzo = mUseLzo.isChecked();
        mProfile.mUseLegacyProvider = mUseLegacyProvider.isChecked();
        mProfile.mAuthenticationType = mType.getSelectedItemPosition();
        mProfile.mPKCS12Filename = mpkcs12.getData();
        mProfile.mPKCS12Password = mPKCS12Password.getText().toString();

        mProfile.mPassword = mPassword.getText().toString();
        mProfile.mUsername = mUserName.getText().toString();
        mProfile.mKeyPassword = mKeyPassword.getText().toString();
        mProfile.mAuthRetry = mAuthRetry.getSelectedItemPosition();
        mProfile.mCheckPeerFingerprint = mEnablePeerFingerprint.isChecked();
        mProfile.mPeerFingerPrints = mPeerFingerprints.getText().toString();
        mProfile.mCompatMode = Utils.mapCompatMode(mCompatMode.getSelectedItemPosition());
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        savePreferences();
        if (mProfile != null) {
            outState.putString(getActivity().getPackageName() + "profileUUID", mProfile.getUUID().toString());
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }


    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (buttonView == mEnablePeerFingerprint)
        {
            mPeerFingerprints.setVisibility(isChecked ? View.VISIBLE : View.GONE);

        }
    }
}
