package cmd

import (
	"fmt"
	"os"

	"github.com/coreos/etcd-ca/third_party/github.com/codegangsta/cli"

	"github.com/coreos/etcd-ca/depot"
	"github.com/coreos/etcd-ca/pkix"
)

func NewNewCertCommand() cli.Command {
	return cli.Command{
		Name:        "new-cert",
		Usage:       "Create certificate request for host",
		Description: "Create certificate for host, including certificate signing request and key. Certificate could be generated by signing the request.",
		Flags: []cli.Flag{
			cli.StringFlag{"passphrase", "", "Passphrase to encrypt private-key PEM block"},
			cli.StringFlag{"ip", "127.0.0.1", "IP address of the host"},
			cli.IntFlag{"key-bits", 4096, "Bit size of RSA keypair to generate"},
		},
		Action: newCertAction,
	}
}

func newCertAction(c *cli.Context) {
	if len(c.Args()) != 1 {
		fmt.Fprintln(os.Stderr, "One host name must be provided.")
		os.Exit(1)
	}
	name := c.Args()[0]

	if depot.CheckCertificateSigningRequest(d, name) || depot.CheckPrivateKeyHost(d, name) {
		fmt.Fprintln(os.Stderr, "Certificate request has existed!")
		os.Exit(1)
	}

	var passphrase []byte
	var err error
	if c.IsSet("passphrase") {
		passphrase = []byte(c.String("passphrase"))
	} else {
		passphrase, err = createPassPhrase()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
	}

	key, err := pkix.CreateRSAKey(c.Int("key-bits"))
	if err != nil {
		fmt.Fprintln(os.Stderr, "Create RSA Key error:", err)
		os.Exit(1)
	} else {
		fmt.Printf("Created %s/key\n", name)
	}

	csr, err := pkix.CreateCertificateSigningRequest(key, name, c.String("ip"))
	if err != nil {
		fmt.Fprintln(os.Stderr, "Create certificate request error:", err)
		os.Exit(1)
	} else {
		fmt.Printf("Created %s/crt\n", name)
	}

	if err = depot.PutCertificateSigningRequest(d, name, csr); err != nil {
		fmt.Fprintln(os.Stderr, "Save certificate request error:", err)
	}
	if err = depot.PutEncryptedPrivateKeyHost(d, name, key, passphrase); err != nil {
		fmt.Fprintln(os.Stderr, "Save key error:", err)
	}
}
