#!/usr/local/bin/python3.8

# Written by Ross Cohen
# Maintained by Chris Hutchinson
# See LICENSE.txt for license information

from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import str
try:
    import Codeville.db
except ImportError:
    import sys, os.path
    from os.path import dirname, abspath, join
    pypath = "lib/python%d.%d/site-packages" % \
                (sys.version_info[0], sys.version_info[1])
    base   = dirname(dirname(abspath(sys.argv[0])))
    sys.path[0:0] = [ join(base, pypath) ]  # first place to look

from Codeville.passwd import Passwd
from configparser import ConfigParser
from getopt import getopt, GetoptError
from getpass import getpass
from os import getcwd, path
from sys import argv, exit, platform

def print_help():
    print("Available options are:\n\t-c <config file>\n\t-f <password file>")
    print('Available commands are: add, set, delete')

def run(args):
    try:
        optlist, args = getopt(args, 'c:f:')
    except GetoptError:
        print('Bad options')
        print_help()
        return 1

    noconfig = False
    if platform == 'win32':
        noconfig = True
    else:
        config_file = '/etc/cdvserver.conf'

    # do a first pass of the command line to pick up an alternate config
    for (opt, arg) in optlist:
        if opt == '-c':
            config_file = arg
        if opt == '-f':
            noconfig = True

    config = ConfigParser()

    config.add_section('control')
    if platform == 'win32':
        config.set('control', 'datadir', getcwd())
    else:
        config.set('control', 'datadir', '/var/lib/cdvserver')

    if not noconfig:
        try:
            confighandle = open(config_file, 'rU')
        except IOError as msg:
            print('Unable to open config file: ' + str(msg))
            return 1

        config.readfp(confighandle)
        confighandle.close()

    passwd_file = path.join(config.get('control', 'datadir'), 'passwd')

    for (opt, arg) in optlist:
        if opt == '-f':
            passwd_file = arg

    if len(args) == 0:
        print_help()
        return 1

    try:
        pw = Passwd(passwd_file, create=1)
    except IOError as msg:
        print('Unable to read password file: ' + str(msg))
        return 1

    if args[0] == 'add':
        if len(args) != 2:
            print('add takes argument <user>')
            return 1
        try:
            pw.get(args[1])
        except KeyError:
            pass
        else:
            print('User exists')
            return 1
        password = getpass('Password: ')
        conf = getpass('Confirm password: ')
        if conf != password:
            print('Confirmation failed')
            return 1
        pw.add(args[1], password)
        print('User added')

    elif args[0] == 'set':
        if len(args) != 2:
            print('set takes argument <user>')
            return 1
        try:
            pw.get(args[1])
        except KeyError:
            print('No such user')
            return 1
        password = getpass('Password: ')
        conf = getpass('Confirm password: ')
        if conf != password:
            print('Confirmation failed')
            return 1
        pw.set(args[1], password)
        print('Password set')

    elif args[0] == 'delete':
        if len(args) != 2:
            print('delete takes argument <user>')
            return 1
        try:
            pw.delete(args[1])
        except ValueError as msg:
            print(str(msg))
            return 1
        print('User deleted')
        return 0

    else:
        print('Unknown command')
        print_help()
        return 1

    return 0

if __name__ == '__main__':
    exit(run(argv[1:]))
