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

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.net.http.SslCertificate;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TabHost;
import android.widget.TextView;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore;

public class TrustedCredentialsSettings extends Fragment {

    private static final String TAG = "TrustedCredentialsSettings";

    private enum Tab {
        SYSTEM("system",
               R.string.trusted_credentials_system_tab,
               R.id.system_tab,
               R.id.system_progress,
               R.id.system_list,
               true),
        USER("user",
             R.string.trusted_credentials_user_tab,
             R.id.user_tab,
             R.id.user_progress,
             R.id.user_list,
             false);

        private final String mTag;
        private final int mLabel;
        private final int mView;
        private final int mProgress;
        private final int mList;
        private final boolean mCheckbox;
        private Tab(String tag, int label, int view, int progress, int list, boolean checkbox) {
            mTag = tag;
            mLabel = label;
            mView = view;
            mProgress = progress;
            mList = list;
            mCheckbox = checkbox;
        }
        private Set<String> getAliases(TrustedCertificateStore store) {
            switch (this) {
                case SYSTEM:
                    return store.allSystemAliases();
                case USER:
                    return store.userAliases();
            }
            throw new AssertionError();
        }
        private boolean deleted(TrustedCertificateStore store, String alias) {
            switch (this) {
                case SYSTEM:
                    return !store.containsAlias(alias);
                case USER:
                    return false;
            }
            throw new AssertionError();
        }
        private int getButtonLabel(CertHolder certHolder) {
            switch (this) {
                case SYSTEM:
                    if (certHolder.mDeleted) {
                        return R.string.trusted_credentials_enable_label;
                    }
                    return R.string.trusted_credentials_disable_label;
                case USER:
                    return R.string.trusted_credentials_remove_label;
            }
            throw new AssertionError();
        }
        private int getButtonConfirmation(CertHolder certHolder) {
            switch (this) {
                case SYSTEM:
                    if (certHolder.mDeleted) {
                        return R.string.trusted_credentials_enable_confirmation;
                    }
                    return R.string.trusted_credentials_disable_confirmation;
                case USER:
                    return R.string.trusted_credentials_remove_confirmation;
            }
            throw new AssertionError();
        }
        private void postOperationUpdate(boolean ok, CertHolder certHolder) {
            if (ok) {
                if (certHolder.mTab.mCheckbox) {
                    certHolder.mDeleted = !certHolder.mDeleted;
                } else {
                    certHolder.mAdapter.mCertHolders.remove(certHolder);
                }
                certHolder.mAdapter.notifyDataSetChanged();
            } else {
                // bail, reload to reset to known state
                certHolder.mAdapter.load();
            }
        }
    }

    // be careful not to use this on the UI thread since it is does file operations
    private final TrustedCertificateStore mStore = new TrustedCertificateStore();

    private TabHost mTabHost;

    @Override public View onCreateView(
            LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        mTabHost = (TabHost) inflater.inflate(R.layout.trusted_credentials, parent, false);
        mTabHost.setup();
        addTab(Tab.SYSTEM);
        // TODO add Install button on Tab.USER to go to CertInstaller like KeyChainActivity
        addTab(Tab.USER);
        return mTabHost;
    }

    private void addTab(Tab tab) {
        TabHost.TabSpec systemSpec = mTabHost.newTabSpec(tab.mTag)
                .setIndicator(getActivity().getString(tab.mLabel))
                .setContent(tab.mView);
        mTabHost.addTab(systemSpec);

        ListView lv = (ListView) mTabHost.findViewById(tab.mList);
        final TrustedCertificateAdapter adapter = new TrustedCertificateAdapter(tab);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
                showCertDialog(adapter.getItem(pos));
            }
        });
    }

    private class TrustedCertificateAdapter extends BaseAdapter {
        private final List<CertHolder> mCertHolders = new ArrayList<CertHolder>();
        private final Tab mTab;
        private TrustedCertificateAdapter(Tab tab) {
            mTab = tab;
            load();
        }
        private void load() {
            new AliasLoader().execute();
        }
        @Override public int getCount() {
            return mCertHolders.size();
        }
        @Override public CertHolder getItem(int position) {
            return mCertHolders.get(position);
        }
        @Override public long getItemId(int position) {
            return position;
        }
        @Override public View getView(int position, View view, ViewGroup parent) {
            ViewHolder holder;
            if (view == null) {
                LayoutInflater inflater = LayoutInflater.from(getActivity());
                view = inflater.inflate(R.layout.trusted_credential, parent, false);
                holder = new ViewHolder();
                holder.mSubjectPrimaryView = (TextView)
                        view.findViewById(R.id.trusted_credential_subject_primary);
                holder.mSubjectSecondaryView = (TextView)
                        view.findViewById(R.id.trusted_credential_subject_secondary);
                holder.mCheckBox = (CheckBox) view.findViewById(R.id.trusted_credential_status);
                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }
            CertHolder certHolder = mCertHolders.get(position);
            holder.mSubjectPrimaryView.setText(certHolder.mSubjectPrimary);
            holder.mSubjectSecondaryView.setText(certHolder.mSubjectSecondary);
            if (mTab.mCheckbox) {
                holder.mCheckBox.setChecked(!certHolder.mDeleted);
                holder.mCheckBox.setVisibility(View.VISIBLE);
            }
            return view;
        };

        private class AliasLoader extends AsyncTask<Void, Integer, List<CertHolder>> {
            ProgressBar mProgressBar;
            View mList;
            @Override protected void onPreExecute() {
                View content = mTabHost.getTabContentView();
                mProgressBar = (ProgressBar) content.findViewById(mTab.mProgress);
                mList = content.findViewById(mTab.mList);
                mProgressBar.setVisibility(View.VISIBLE);
                mList.setVisibility(View.GONE);
            }
            @Override protected List<CertHolder> doInBackground(Void... params) {
                Set<String> aliases = mTab.getAliases(mStore);
                int max = aliases.size();
                int progress = 0;
                List<CertHolder> certHolders = new ArrayList<CertHolder>(max);
                for (String alias : aliases) {
                    X509Certificate cert = (X509Certificate) mStore.getCertificate(alias, true);
                    certHolders.add(new CertHolder(mStore,
                                                   TrustedCertificateAdapter.this,
                                                   mTab,
                                                   alias,
                                                   cert));
                    publishProgress(++progress, max);
                }
                Collections.sort(certHolders);
                return certHolders;
            }
            @Override protected void onProgressUpdate(Integer... progressAndMax) {
                int progress = progressAndMax[0];
                int max = progressAndMax[1];
                if (max != mProgressBar.getMax()) {
                    mProgressBar.setMax(max);
                }
                mProgressBar.setProgress(progress);
            }
            @Override protected void onPostExecute(List<CertHolder> certHolders) {
                mCertHolders.clear();
                mCertHolders.addAll(certHolders);
                notifyDataSetChanged();
                View content = mTabHost.getTabContentView();
                mProgressBar.setVisibility(View.GONE);
                mList.setVisibility(View.VISIBLE);
                mProgressBar.setProgress(0);
            }
        }
    }

    private static class CertHolder implements Comparable<CertHolder> {
        private final TrustedCertificateStore mStore;
        private final TrustedCertificateAdapter mAdapter;
        private final Tab mTab;
        private final String mAlias;
        private final X509Certificate mX509Cert;

        private final SslCertificate mSslCert;
        private final String mSubjectPrimary;
        private final String mSubjectSecondary;
        private boolean mDeleted;

        private CertHolder(TrustedCertificateStore store,
                           TrustedCertificateAdapter adapter,
                           Tab tab,
                           String alias,
                           X509Certificate x509Cert) {
            mStore = store;
            mAdapter = adapter;
            mTab = tab;
            mAlias = alias;
            mX509Cert = x509Cert;

            mSslCert = new SslCertificate(x509Cert);

            String cn = mSslCert.getIssuedTo().getCName();
            String o = mSslCert.getIssuedTo().getOName();
            String ou = mSslCert.getIssuedTo().getUName();
            // if we have a O, use O as primary subject, secondary prefer CN over OU
            // if we don't have an O, use CN as primary, empty secondary
            // if we don't have O or CN, use DName as primary, empty secondary
            if (!o.isEmpty()) {
                if (!cn.isEmpty()) {
                    mSubjectPrimary = o;
                    mSubjectSecondary = cn;
                } else {
                    mSubjectPrimary = o;
                    mSubjectSecondary = ou;
                }
            } else {
                if (!cn.isEmpty()) {
                    mSubjectPrimary = cn;
                    mSubjectSecondary = "";
                } else {
                    mSubjectPrimary = mSslCert.getIssuedTo().getDName();
                    mSubjectSecondary = "";
                }
            }
            mDeleted = mTab.deleted(mStore, mAlias);
        }
        @Override public int compareTo(CertHolder o) {
            int primary = this.mSubjectPrimary.compareToIgnoreCase(o.mSubjectPrimary);
            if (primary != 0) {
                return primary;
            }
            return this.mSubjectSecondary.compareToIgnoreCase(o.mSubjectSecondary);
        }
        @Override public boolean equals(Object o) {
            if (!(o instanceof CertHolder)) {
                return false;
            }
            CertHolder other = (CertHolder) o;
            return mAlias.equals(other.mAlias);
        }
        @Override public int hashCode() {
            return mAlias.hashCode();
        }
    }

    private static class ViewHolder {
        private TextView mSubjectPrimaryView;
        private TextView mSubjectSecondaryView;
        private CheckBox mCheckBox;
    }

    private void showCertDialog(final CertHolder certHolder) {
        View view = certHolder.mSslCert.inflateCertificateView(getActivity());
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(com.android.internal.R.string.ssl_certificate);
        builder.setView(view);
        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override public void onClick(DialogInterface dialog, int id) {
                dialog.dismiss();
            }
        });
        final Dialog certDialog = builder.create();

        ViewGroup body = (ViewGroup) view.findViewById(com.android.internal.R.id.body);
        LayoutInflater inflater = LayoutInflater.from(getActivity());
        Button removeButton = (Button) inflater.inflate(R.layout.trusted_credential_details,
                                                        body,
                                                        false);
        body.addView(removeButton);
        removeButton.setText(certHolder.mTab.getButtonLabel(certHolder));
        removeButton.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setMessage(certHolder.mTab.getButtonConfirmation(certHolder));
                builder.setPositiveButton(
                        android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override public void onClick(DialogInterface dialog, int id) {
                        new AliasOperation(certHolder).execute();
                        dialog.dismiss();
                        certDialog.dismiss();
                    }
                });
                builder.setNegativeButton(
                        android.R.string.no, new DialogInterface.OnClickListener() {
                    @Override public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });
                AlertDialog alert = builder.create();
                alert.show();
            }
        });

        certDialog.show();
    }

    private class AliasOperation extends AsyncTask<Void, Void, Boolean> {
        private final CertHolder mCertHolder;
        private AliasOperation(CertHolder certHolder) {
            mCertHolder = certHolder;
        }
        @Override protected Boolean doInBackground(Void... params) {
            try {
                KeyChainConnection keyChainConnection = KeyChain.bind(getActivity());
                IKeyChainService service = keyChainConnection.getService();
                try {
                    if (mCertHolder.mDeleted) {
                        byte[] bytes = mCertHolder.mX509Cert.getEncoded();
                        service.installCaCertificate(bytes);
                        return true;
                    } else {
                        return service.deleteCaCertificate(mCertHolder.mAlias);
                    }
                } finally {
                    keyChainConnection.close();
                }
            } catch (CertificateEncodingException e) {
                return false;
            } catch (IllegalStateException e) {
                // used by installCaCertificate to report errors
                return false;
            } catch (RemoteException e) {
                return false;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
        @Override protected void onPostExecute(Boolean ok) {
            mCertHolder.mTab.postOperationUpdate(ok, mCertHolder);
        }
    }
}
