# Copyright 3D Control Systems, Inc. All Rights Reserved 2017-2019.
# Built in San Francisco.

# This software is distributed under a commercial license for personal,
# educational, corporate or any other use.
# The software as a whole or any parts of it is prohibited for distribution or
# use without obtaining a license from 3D Control Systems, Inc.

# All software licenses are subject to the 3DPrinterOS terms of use
# (available at https://www.3dprinteros.com/terms-and-conditions/),
# and privacy policy (available at https://www.3dprinteros.com/privacy-policy/)

import sys
import crypt
import logging


if sys.version_info[0] < 3:
    import random
    def mksalt(): # TODO check this generator randomness
        ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        random_line = "".join((random.choice(ALPHABET) for _ in range(0,16)))
        return "$6$" + random_line
else:
    from crypt import mksalt as mksalt


def generate_new_password(password):
    logging.getLogger(__name__).info("Generating new password line")
    return crypt.crypt(password, mksalt() + "$")


def change_password(shadow_path, password, user_name_to_change_password="root", user_names_to_remove=[]):
    logger = logging.getLogger(__name__)
    logger.info("Reading " + shadow_path)
    shadow_output_text = ""
    with open(shadow_path, "r") as f:
        shadow_input_text = f.read()
    for line in shadow_input_text.split("\n"):
        if line.startswith(user_name_to_change_password):
            line_list = line.split(":")
            line = line.replace(line_list[1], generate_new_password(password))
        else:
            for name in user_names_to_remove:
                if line.startswith(name):
                    logger.info("Removing user %s from %s" % (name, shadow_path))
                    line = ""
        if line:
            shadow_output_text += line + "\n"
    logger.info("Writing password to " + shadow_path)
    with open(shadow_path, "w") as f:
        f.write(shadow_output_text)
    logger.info("Success!")


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Error: not enough arguments.\nUsage: python patch_shadow.py path_to_shadow_file new_password\n")
        sys.exit(1)
    else:
        logging.basicConfig(level=logging.DEBUG, format='%(message)s')
        shadow_path = sys.argv[1]
        password = sys.argv[2]
        user_names_to_remove = ['pi', 'orange']
        change_password(shadow_path, password, user_names_to_remove=user_names_to_remove)

