package com.greenautomation.pkeytool;

import java.io.PrintStream;
import java.security.KeyStore;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.text.*;
import java.util.*;

/**
 * The pkeytool -list command.<p>
 *
 * Copyright 2003 Green Automation, Inc.<p>
 *
 * This file is part of pkeytool.<p>
 *
 * pkeytool is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.<p>
 *
 * pkeytool is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.<p>
 *
 * You should have received a copy of the GNU General Public License
 * along with pkeytool; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * @author David Green &lt;green@couchpotato.net&gt;
 * @version $Id: ListCommand.java,v 1.2 2004/08/04 19:09:12 green Exp $
 */
public class ListCommand implements Command {

    private final DateFormat format = new SimpleDateFormat("MMM d, yyyy");

    public void run(Map args) throws Exception {
        boolean verbose = args.get("-v") != null;
        boolean rfc = args.get("-rfc") != null;
        if (verbose && rfc) {
            throw new PKeyToolException(
                    "Must not specify both -v and -rfc with 'list' command");
        }
        String onlyAlias = (String) args.get("-alias");
        KeyStore keystore = Utils.openKeyStore(args, false, false);
        int certEntries = 0;
        if (onlyAlias == null) {
            boolean first = true;
            Enumeration e = keystore.aliases();
            while (e.hasMoreElements()) {
                String alias = (String) e.nextElement();
                if (keystore.isKeyEntry(alias)) {
                    printInfo(keystore, alias, verbose, rfc, first);
                    first = false;
                }
                else {
                    certEntries++;
                }
            }
        }
        else {
            if (keystore.isKeyEntry(onlyAlias)) {
                printInfo(keystore, onlyAlias, verbose, rfc, true);
            }
            else {
                certEntries++;
            }
        }
        if (certEntries != 0) {
            char[] line = ("* Ignored " + certEntries +
                    " trustedCertEntry records; use keytool to view them. *"
                    ).toCharArray();
            char[] border = new char[line.length];
            Arrays.fill(border, '*');
            System.out.println(border);
            System.out.println(line);
            System.out.println(border);
        }
    }

    public String getName() {
        return "-list";
    }

    public String[] getParamsWithArgs() {
        return new String[] {"-keystore", "-alias", "-storetype"};
    }

    public String[] getParamsWithoutArgs() {
        return new String[] {"-v", "-rfc"};
    }

    public void printHelp(PrintStream s) {
        s.println("-list        [-v | -rfc] [-keystore <keystore>] [-alias <alias>]");
        s.println("             [-storetype <storetype>]");
    }

    private void printInfo(KeyStore keystore, String alias, boolean verbose,
            boolean rfc, boolean first)
            throws Exception {
        if (verbose || rfc) {
            Certificate[] cert = keystore.getCertificateChain(alias);
            String creationDate = format.format(keystore.getCreationDate(alias));
            System.out.println("Alias name: " + alias);
            System.out.println("Creation date: " + creationDate);
            System.out.println("Entry type: keyEntry");
            System.out.println("Certificate chain length: " + cert.length);
            for (int i=0; i < cert.length; i++) {
                X509Certificate xcert = (X509Certificate) cert[i];
                System.out.println("Certificate[" + (i + 1) + "]:");
                if (rfc) {
                    Utils.writeArmored(System.out, xcert.getEncoded(), "CERTIFICATE", 76);
                }
                else {
                    System.out.println("Owner: " + xcert.getSubjectDN());
                    System.out.println("Issuer: " + xcert.getIssuerDN());
                    System.out.println("Serial number: " +
                                       xcert.getSerialNumber().toString(16));
                    System.out.println("Valid from: " + xcert.getNotBefore() +
                                       " until: " + xcert.getNotAfter());
                    System.out.println("Certificate fingerprints:");
                    System.out.println("         MD5:  " +
                                       Utils.getFingerprint(xcert, "MD5"));
                    System.out.println("         SHA1: " +
                                       Utils.getFingerprint(xcert, "SHA1"));
                }
            }
            if (!first) {
                System.out.println();
                System.out.println();
                System.out.println("*******************************************");
                System.out.println("*******************************************");
                System.out.println();
                System.out.println();
            }
        }
        else {
            Certificate cert = keystore.getCertificate(alias);
            String creationDate = format.format(keystore.getCreationDate(alias));
            System.out.println(alias + ", " + creationDate + ", keyEntry");
            System.out.println("Certificate fingerprint (MD5): " +
                               Utils.getFingerprint(cert, "MD5"));
        }
    }

}