#!/usr/bin/env python3
#
#  Interactive script to create a ssh key, encrypting the private
#  part. Keys are generated with names like build-deps/user.enc and
#  build-deps/user.pub. The 'user' part is derived from an ssh url
#  given to script.
#
#  Tke key is used by the git-push script.
#
#  Copyright (c) 2021 ALec Leamas

# This program 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 3 of the License, or
# (at your option) any later version.

import base64
import getpass
import os
import subprocess
import sys

from cryptography.fernet import Fernet, InvalidToken
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC


exit_msg = """
New ssh key created and encrypted.Todo:

  - Commit the new ssh keys build-deps/%s.pub and build-deps/%s.enc.
  - Add the ssh url as GIT_REPO environment variable in builder.
  - Add password as GIT_KEY_PASSWORD environment variable in builder.
  - Add the public key build-deps/%s.pub below to the github account:
"""

clone_warning = \
   "Url doesn't seem to be a clone of https://github.com/OpenCPN/plugins.git"

def cipherFernet(password):
    key = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=b'abcd',
                     iterations=1000,
                     backend=default_backend()).derive(password)
    return Fernet(base64.urlsafe_b64encode(key))

def encrypt1(plaintext, password):
    return cipherFernet(password).encrypt(plaintext)


def get_user():
    """ Make ssh url sanity checks, return user name derived from URL."""
    print("Enter ssh URL for ocpn-plugins.xml clone: ", end='')
    url = input().strip()
    if (not url.startswith("git@")):
        print("This is not a SSH url. Giving up.")
        sys.exit(1)
    if (not url.endswith("plugins.git")):
        print("\nWarning: " +  clone_warning + "\n")
    user = url.split(':')[1]
    user = user.split('/')[0]
    return user


def get_password():
    while True:
       pw1 = getpass.getpass(prompt="Enter password for encrypting new key: ")
       pw2 = getpass.getpass(prompt="Repeat password: ")
       if pw1 == pw2:
           return pw1
       print("They don't match, try again")


def main():
    """Indeed: main function."""
    ci_dir = os.path.dirname(sys.argv[0])
    os.chdir(os.path.join(ci_dir, '..'))
    user = get_user()
    new_key_cmd = ['ssh-keygen', '-f', "build-deps/" + user, '-N', '']
    subprocess.check_call(new_key_cmd)
    print("\nNew key build-deps/%s  successfully created\n" % user)
    pw = get_password()
    with open("build-deps/" + user, 'r') as f:
        key = f.read()
    key = encrypt1(key.encode(), pw.encode())
    with open("build-deps/%s.enc" % user, 'w') as f:
        f.write(key.decode('utf-8'))
    os.remove("build-deps/" + user)
    print(exit_msg.replace("%s", user))
    with open("build-deps/%s.pub" % user, 'r') as f:
        pub_key = f.read()
    print(pub_key)


if __name__ == '__main__':
    main()
