# encoding: utf-8
import json
import logging
import os
from six import StringIO
import subprocess
import tempfile


logger = logging.getLogger(__name__)


_std_subj = {
    "C": "PL",
    "ST": "Mazowieckie",
    "L": "Warsaw",
    "O": "Warsaw Hackerspace",
    "OU": "clustercfg",
}

_ca_csr = {
  "CN": "Prototype Test Certificate Authority",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [ _std_subj ],
}

_ca_config = {
  "signing": {
    "default": {
      "expiry": "168h"
    },
    "profiles": {
      "intermediate": {
        "expiry": "8760h",
        "usages": [
          "signing",
          "key encipherment",
          "cert sign",
          "crl sign",
          "server auth",
          "client auth",
        ],
        "ca_constraint": {
          "is_ca": True,
        },
      },
      "server": {
        "expiry": "8760h",
        "usages": [
          "signing",
          "key encipherment",
          "server auth"
        ]
      },
      "client": {
        "expiry": "8760h",
        "usages": [
          "signing",
          "key encipherment",
          "client auth"
        ]
      },
      "client-server": {
        "expiry": "8760h",
        "usages": [
          "signing",
          "key encipherment",
          "server auth",
          "client auth"
        ]
      }
    }
  }
}


class CAException(Exception):
    pass


class CA(object):
    def __init__(self, secretstore, certdir, short, cn):
        self.ss = secretstore
        self.cdir = certdir
        self.short = short
        self.cn = cn
        self._init_ca()

    def __str__(self):
        return 'CN={} ({})'.format(self.cn, self.short)

    @property
    def _secret_key(self):
        return 'ca-{}.key'.format(self.short)

    @property
    def _cert(self):
        return os.path.join(self.cdir, 'ca-{}.crt'.format(self.short))

    @property
    def cert_data(self):
        with open(self._cert) as f:
            return f.read()

    def _cfssl_call(self, args, obj=None, stdin=None):
        p = subprocess.Popen(['cfssl'] + args,
                             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        if obj is not None:
            stdin = json.dumps(obj)

        outs, errs = p.communicate(stdin.encode())
        if p.returncode != 0:
            raise Exception(
                'cfssl failed. stderr: %r, stdout: %r, code: %r' % (
                    errs, outs, p.returncode))

        out = json.loads(outs)
        return out

    def _init_ca(self):
        if self.ss.exists(self._secret_key):
            return

        ca_csr = dict(_ca_csr)
        ca_csr['CN'] = self.cn

        logger.info("{}: Generating CA...".format(self))
        out = self._cfssl_call(['gencert', '-initca', '-'], obj=ca_csr)

        f = self.ss.open(self._secret_key, 'w')
        f.write(out['key'])
        f.close()

        f = open(self._cert, 'w')
        f.write(out['cert'])
        f.close()

    def gen_key(self, hosts, o=_std_subj['O'], ou=_std_subj['OU'], save=None):
        """お元気ですか？"""
        cfg = {
            "CN": hosts[0],
            "hosts": hosts,
            "key": {
                "algo": "rsa",
                "size": 4096,
            },
            "names": [
                {
                    "C": _std_subj["C"],
                    "ST": _std_subj["ST"],
                    "L": _std_subj["L"],
                    "O": o,
                    "OU": ou,
                },
            ],
        }
        cfg.update(_ca_config)
        logger.info("{}: Generating key/CSR for {}".format(self, hosts))
        out = self._cfssl_call(['genkey', '-'], obj=cfg)

        key, csr = out['key'], out['csr']
        if save is not None:
            logging.info("{}: Saving new key to secret {}".format(self, save))
            f = self.ss.open(save, 'w')
            f.write(key)
            f.close()

        return key, csr

    def sign(self, csr, save=None, profile='client-server'):
        logging.info("{}: Signing CSR".format(self))
        ca = self._cert
        cakey = self.ss.plaintext(self._secret_key)

        config = tempfile.NamedTemporaryFile(mode='w')
        json.dump(_ca_config, config)
        config.flush()

        out = self._cfssl_call(['sign', '-ca=' + ca, '-ca-key=' + cakey,
                                '-profile='+profile, '-config='+config.name, '-'], stdin=csr)
        cert = out['cert']
        if save is not None:
            name = os.path.join(self.cdir, save)
            logging.info("{}: Saving new certificate to {}".format(self, name))
            f = open(name, 'w')
            f.write(cert)
            f.close()

        config.close()
        return cert

    def upload(self, c, remote_cert):
        logger.info("Uploading CA {} to {}".format(self, remote_cert))
        c.put(local=self._cert, remote=remote_cert)

    def make_cert(self, *a, **kw):
        return ManagedCertificate(self, *a, **kw)


class ManagedCertificate(object):
    def __init__(self, ca, name, hosts, o=None, ou=None, profile='client-server'):
        self.ca = ca

        self.hosts = hosts
        self.name = name
        self.key = '{}.key'.format(name)
        self.cert = '{}.cert'.format(name)
        self.o = o
        self.ou = ou
        self.profile = profile

        self.ensure()

    def __str__(self):
        return '{}'.format(self.name)

    @property
    def key_exists(self):
        return self.ca.ss.exists(self.key)

    @property
    def key_data(self):
        f = open(self.ca.ss.open(self.key))
        d = f.read()
        f.close()
        return d

    @property
    def key_path(self):
        return self.ca.ss.plaintext(self.key)

    @property
    def cert_path(self):
        return os.path.join(self.ca.cdir, self.cert)

    @property
    def cert_exists(self):
        return os.path.exists(self.cert_path)

    @property
    def cert_data(self):
        with open(self.cert_path) as f:
            return f.read()

    def ensure(self):
        if self.key_exists and self.cert_exists:
            return

        logger.info("{}: Generating...".format(self))
        key, csr = self.ca.gen_key(self.hosts, o=self.o, ou=self.ou, save=self.key)
        self.ca.sign(csr, save=self.cert, profile=self.profile)

    def upload(self, c, remote_cert, remote_key, concat_ca=False):
        logger.info("Uploading Cert {} to {} & {}".format(self, remote_cert, remote_key))
        if concat_ca:
            f = StringIO(self.cert_data + self.ca.cert_data)
            c.put(local=f, remote=remote_cert)
        else:
            c.put(local=self.cert_path, remote=remote_cert)
        c.put(local=self.key_path, remote=remote_key)

    def upload_pki(self, c, pki, concat_ca=False):
        self.upload(c, pki['cert'], pki['key'], concat_ca)
