#!/usr/bin/env cspython

""" Create a hubpwfile used for password authentication with a CodeSonar hub.

    Requires CodeSonar csypython.
"""

import argparse
import os
import sys

try:
    import gtr
except ImportError:
    print("This script must be executed with CodeSonar CSPYTHON")
    sys.exit(1)


def mkdirs_owner_only(dir_path):
    """ Make a sequence of directories which will have user/owner access only. """
    dir_stack = []
    parent_dir = dir_path
    while parent_dir and not os.path.exists(parent_dir):
        dir_stack.append(parent_dir)
        parent_dir2 = os.path.dirname(parent_dir)
        if parent_dir2 == parent_dir:
            parent_dir2 = ''
        parent_dir = parent_dir2
    for parent_dir in reversed(dir_stack):
        gtr.file_mkdir_owner_only(parent_dir)


def main(argv, stdio):
    stderr = stdio[2]
    exit_code = 0
    arg_parser = argparse.ArgumentParser(
        description="Prompt for a password and create an unencrypted password file to be used with a CodeSonar hub.")
    arg_parser.add_argument(
        'hubpwfile',
        help="Name of file to create.  File will be created with user/owner-only permission.")
    arg_parser.add_argument(
        "--prompt",
        default="Password: ",
        help="Password prompt message to print on STDERR.")
    arg_parser.add_argument(
        "-p", "--make-dirs", "--mkdirs" "--parents",
        dest='make_dirs',
        action='store_true',
        help="Create all intermediate directories in the file path as needed.  Directories will be created with user/owner-only permission.")
    arg_parser.add_argument(
        "-f", "--overwrite",
        dest='overwrite',
        action='store_true',
        help="Overwrite any existing password file.  Implies --mkdirs")
    arg_obj = arg_parser.parse_args(argv[1:])
    hubpwfile = arg_obj.hubpwfile
    prompt = arg_obj.prompt
    should_make_dirs = arg_obj.make_dirs
    should_overwrite = arg_obj.overwrite
    assert hubpwfile
    if should_overwrite:
        should_make_dirs = True
    password = None
    if os.path.exists(hubpwfile) and not should_overwrite:
        stderr.write("File exists, will not overwrite: %s\n" % hubpwfile)
        exit_code = 1
    else:
        hubpwfile_dir = os.path.dirname(hubpwfile)
        if hubpwfile_dir and not os.path.exists(hubpwfile_dir) and not should_make_dirs:
            stderr.write("Directory does not exist: %s\n" % hubpwfile_dir)
            exit_code = 1
        else:
            password = gtr.getpass(prompt)
            stderr.write("\n")
            # Only create directories after we successfully get a password from the user:
            #  If user hits CTRL-C at password prompt, we don't want directories to be created.
            if hubpwfile_dir and not os.path.exists(hubpwfile_dir) and should_make_dirs:
                stderr.write("Creating directory: %s\n" % hubpwfile_dir)
                mkdirs_owner_only(hubpwfile_dir)
    if password is not None:
        stderr.write("Writing file: %s\n" % hubpwfile)
        # Create the file, but leave it empty temporarily:
        with open(hubpwfile, 'w') as hubpwfile_io:
            pass
        # Change permission to be owner only:
        gtr.file_make_path_owner_only(hubpwfile)
        # Now we can insert the password into the file:
        with open(hubpwfile, 'w') as hubpwfile_io:
            hubpwfile_io.write(password)
    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv, (sys.stdin, sys.stdout, sys.stderr)))
