#!/usr/bin/env python3

import argparse
import csv
from os.path import abspath, dirname, join
from os import getcwd, walk
from shear import shear
from subprocess import check_output

TRUES = ["", "true", "TRUE", "True"]


def find_file(target, dirpath="."):
    found_files = find_files(target, dirpath)
    if len(found_files) > 0:
        return found_files[0]


def find_files(target, dirpath="."):
    found_files = []
    for root, dirs, files in walk(dirpath or "."):
        for filename in files:
            if filename == target:
                filepath = abspath(join(root, filename))
                # skip hidden files
                if not "./" in filepath:
                    found_files.append(filepath)
    return found_files


def exc(cmd, pipfile):
    if pipfile:
        cmd = (
            "cd "
            + dirname(pipfile)
            + ' && pipenv run sh -c "'
            + cmd.replace('"', '\\"')
            + '"'
        )
    print(f"running {cmd}")
    return check_output(cmd, shell=True)


def makemigrations(manage_py, pipfile):
    print(exc(f"python3 {manage_py} makemigrations", pipfile))


def migrate(manage_py, pipfile):
    print(exc(f"python3 {manage_py} migrate", pipfile))


def collectstatic(manage_py, pipfile):
    print(exc(f'echo "yes" | python3 {manage_py} collectstatic', pipfile))


def run(manage_py, pipfile, filepath):
    print(
        exc(
            '''echo 'exec(open("'''
            + filepath
            + """").read(), {})' | python3 """
            + manage_py
            + " shell",
            pipfile,
        )
    )


def create_user(manage_py, username, email, password, pipfile, debug=False, safe=False):
    try:
        if debug:
            print("starting create_user with", project, username, email, password)

        if username is None:
            raise Exception("[djc] no username given")

        if email is None:
            raise Exception("[djc] no email given")

        command = f"""echo "from django.contrib.auth import get_user_model; User = get_user_model(); print(User.objects.create_user('''{username}''','''{email}''','''{password}'''))" | python3 {manage_py} shell"""
        if debug:
            print("running:", command)

        output = exc(command, pipfile)

        if debug:
            print("output:", output)
        if debug:
            print("created " + username)
    except Exception as e:
        if safe:
            print(e)
        else:
            raise e


def create_superuser(
    manage_py, username, email, password, pipfile, debug=False, safe=False
):
    try:
        if debug:
            print("starting create_superuser with", project, username, email, password)

        if username is None:
            raise Exception("[djc] no username given")

        if email is None:
            raise Exception("[djc] no email given")

        command = f"""echo "from django.contrib.auth import get_user_model; User = get_user_model(); print(User.objects.create_superuser('''{username}''','''{email}''','''{password}'''))" | python3 {manage_py} shell"""
        if debug:
            print("running:", command)

        output = exc(command, pipfile)

        if debug:
            print("output:", output)
        if debug:
            print("created " + username)
    except Exception as e:
        if safe:
            print(e)
        else:
            raise e


if __name__ == "__main__":
    # execute only if run as a script
    parser = argparse.ArgumentParser()
    parser.add_argument("subcommand")
    parser.add_argument("-d", "--debug", choices=TRUES)
    parser.add_argument("-f", "--filepath")
    parser.add_argument("--safe")
    parser.add_argument("-s", "--settings")
    parser.add_argument("-u", "--username")
    parser.add_argument("-e", "--email")
    parser.add_argument("-pw", "--password")
    parser.add_argument("-prj", "--project")
    args = parser.parse_args()
    print("args:", args)

    # if you don't pass in a project path
    # it assumes you are inside a project
    project = args.project if args.project else getcwd()

    project = shear(project)

    manage_py = find_file("manage.py", project)
    print("found manage.py at", manage_py)

    models = find_files("models.py", project)
    for model in models:
        print("found model.py at", model)

    pipfile = find_file("Pipfile", project)
    print("found Pipfile at", pipfile)

    if not manage_py:
        raise Exception("unable to find manage.py")

    subcommand = args.subcommand

    if subcommand == "create-user":
        create_user(
            username=shear(args.username),
            email=shear(args.email),
            password=shear(args.password),
            manage_py=manage_py,
            debug=shear(args.debug) in TRUES,
            pipfile=pipfile,
            safe=shear(args.safe) in TRUES,
        )
    elif subcommand == "create-superuser" or subcommand == "create-super-user":
        create_superuser(
            username=shear(args.username),
            email=shear(args.email),
            password=shear(args.password),
            manage_py=manage_py,
            debug=shear(args.debug) in TRUES,
            pipfile=pipfile,
            safe=shear(args.safe) in TRUES,
        )
    elif subcommand == "makemigrations":
        makemigrations(manage_py=manage_py, pipfile=pipfile)
    elif subcommand == "migrate":
        migrate(manage_py=manage_py, pipfile=pipfile)
    elif subcommand == "run":
        run(manage_py=manage_py, pipfile=pipfile, filepath=shear(args.filepath))
    elif subcommand == "collectstatic":
        collectstatic(manage_py=manage_py, pipfile=pipfile)
