#!/usr/bin/env python3

## TODO: let it set up dev-deps for checking automatically in virtualenv

import sys
import glob
import subprocess

import pickle
import hashlib #instead of md5

from msbase.utils import read_nproc
from msbase.subprocess_ import multiprocess
from msbase.logging import logger

NPROC = read_nproc()

def run(cmd_args):
    print("+ " + " ".join(cmd_args))
    p = subprocess.run(cmd_args)
    return p.returncode == 0

checks = {
    "mypy": lambda f: ["mypy", "--ignore-missing-imports", f],
    # "flake8": lambda f: ["flake8", f, "--count", "--select=E9,F63,F7,F82", "--show-source", "--statistics"],
    "pylint": lambda f: ["pylint", "-E", f]
}

def is_py(f: str):
    if f.endswith(".py"):
        return True
    with open(f, "r") as fh:
        content = fh.read()
        for line in content.split("\n"):
            if line.startswith("#!") and "python" in line:
                return True
    return False

def process(f):
    return all(run(check(f)) for check in checks.values())

if __name__ == "__main__":
    files_to_check = []

    checked = []
    failed = []
    unknowns = []

    try:
        with open("/tmp/ckdb", "rb") as fh:
            l = pickle.load(fh)
    except IOError:
        l = []
    db = dict(l)

    checksum = None

    for pat in sys.argv[1:]:
        for f in glob.glob(pat):
            with open(f) as fh:
                checksum = hashlib.md5(fh.read().encode('utf-8')).hexdigest()
                if db.get(f, None) == checksum:
                    logger.info(f + " is not modified")
                    continue
                if is_py(f):
                    files_to_check.append(f)
                else:
                    unknowns.append(f)

    for f in unknowns:
        logger.warn("[ck] ❓ Ignoring unknown extension: " + f)

    results = multiprocess(process, files_to_check, n=NPROC, return_dict=True, throws=True, verbose=False)

    for f, ok in results.items():
        if ok:
            checked.append(f)
            db[f] = checksum
        else:
            failed.append(f)

    for f in checked:
        logger.info("[ck] ✅ Checked: " + f)

    for f in failed:
        logger.error("[ck] ❌ Failed: " + f)

    with open("/tmp/ckdb", "wb") as fh:
        pickle.dump(list(db.items()), fh)

    if len(failed):
        exit(-1)
