# -*- coding: utf-8 -*-
# vim: set et sts=2:

import logging
import os
import argparse
import requests
import sys
import prettytable
import glob
from slapos.certificate_authority.certificate_authority import CertificateBase

def parseArguments():
  """
  Parse arguments for monitor instance.
  """
  parser = argparse.ArgumentParser()
  parser.add_argument('--ca_dir',
                      help='Path for Certificate Authority folder')
  parser.add_argument('--key',
                      action='append', dest='key_list', default=[],
                      help='Key of the certificate Request to sign')
  parser.add_argument('--ca_url',
                      help='Certificate Authority URL')
  parser.add_argument('--list',
                      default=False, action="store_true",
                      help='List certificates to sign')
  parser.add_argument('--sign',
                      default=False, action="store_true",
                      help='Request sign certificate')

  return parser

def main():
  parser = parseArguments()
  options = parser.parse_args()

  logging.basicConfig(format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
                      stream=sys.stdout ,level=logging.DEBUG)

  if not options.ca_dir:
    options.ca_dir = os.getcwd()
  else:
    options.ca_dir = os.path.abspath(options.ca_dir)
  options.req = os.path.join(options.ca_dir, 'req')

  if options.list:
    exit(listCertificateRequest(options))
  elif options.sign and len(options.key_list) > 0:
    exit(requestSigncertificate(options))

  parser.print_help()
  exit(1)

def listCertificateRequest(options):
  pt = prettytable.PrettyTable(['CN', 'Country', 'City', 'email', 'key'])
  req_directory = os.path.join(options.ca_dir, 'req')
  x509 = CertificateBase()
  file_list = filter(os.path.isfile,
    glob.glob("%s/*.csr.pem" % req_directory)
  )
  for file in file_list:
    # XXX file name is key.csr.pem
    key = os.path.basename(file).split('.')[0]
    req = x509.freadCertificateRequest(file)
    subject = x509.getSubject(req)
    pt.add_row([subject['CN'], subject['C'], subject['ST'],
                subject['emailAddress'], key])

  for line in pt.get_string(border=True, padding_width=0).split('\n'):
    #logging.info(line)
    print line

  return 0

def requestSigncertificate(options):

  req_directory = os.path.join(options.ca_dir, 'req')
  code = 0
  x509 = CertificateBase()

  for key in options.key_list:
    csr_file = os.path.join(req_directory, '%s.csr.pem' % key)
    if not os.path.exists(csr_file):
      logging.error("Cannot get csr on CA from specified key: %s" % key)
      return -2
    req = x509.freadCertificateRequest(csr_file)
    cn = x509.getSubject(req)['CN']

    data = {'key': key}
    logging.info("Signing %s..." % cn)
    response = requests.post('%s/signcert' % options.ca_url, data=data)
    if response.status_code != 200:
      code = -1*response.status_code
      logging.error("ERROR %s: Failed to sign certifice from %s.\n%s" % (
                  response.status_code, cn, response.text))
    else:
      logging.info("%s is signed, server responded with: %s" % (cn,
                    response.text))
  return code
