import subprocess
import os
import magic
from models import *


def git_command(repo, data, *args, return_err=False, return_exit=False):
    if not os.path.isdir(repo):
        raise FileNotFoundError(f"Repo {repo} not found")
    env = os.environ.copy()

    command = ["git", *args]

    proc = subprocess.Popen(" ".join(command), cwd=repo, env=env, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                            stdin=subprocess.PIPE)

    if data:
        proc.stdin.write(data)

    out, err = proc.communicate()
    exit_code = proc.returncode

    result = (out,)

    if return_err:
        result = result + (err,)
    if return_exit:
        result = result + (exit_code,)

    return result[0] if len(result) == 1 else result


def only_chars(string, chars):
    chars = set(chars)
    all_chars = set(string)
    return all_chars.issubset(chars)


def get_permission_level(logged_in, username, repository):
    user = User.query.filter_by(username=logged_in).first()
    repo = Repo.query.filter_by(route=f"/{username}/{repository}").first()

    if user and repo:
        permission = RepoAccess.query.filter_by(user=user, repo=repo).first()
        if permission:
            return permission.access_level

    return None


def get_visibility(username, repository):
    repo = Repo.query.filter_by(route=f"/{username}/{repository}").first()

    if repo:
        return repo.visibility

    return None


def get_favourite(logged_in, username, repository):
    print(logged_in, username, repository)
    relationship = RepoFavourite.query.filter_by(user_username=logged_in,
                                                 repo_route=f"/{username}/{repository}").first()
    return relationship


def human_size(value, decimals=2, scale=1024,
               units=("B", "kiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", "RiB", "QiB")):
    for unit in units:
        if value < scale:
            break
        value /= scale
    if int(value) == value:
        # do not return decimals if the value is already round
        return int(value), unit
    return round(value * 10 ** decimals) / 10 ** decimals, unit


def guess_mime(path):
    if os.path.isdir(path):
        mimetype = "inode/directory"
    elif magic.from_file(path, mime=True):
        mimetype = magic.from_file(path, mime=True)
    else:
        mimetype = "application/octet-stream"
    return mimetype


def convert_to_html(path):
    with open(path, "r") as f:
        contents = f.read()
    return contents
