import uuid

from app import app, User, Repo, db, bcrypt
import os
import shutil
import config
import flask
import git
import subprocess
from flask_httpauth import HTTPBasicAuth
import zlib

auth = HTTPBasicAuth(realm=config.AUTH_REALM)


@auth.verify_password
def verifyPassword(username, password):
    user = User.query.filter_by(username=username).first()

    if user and bcrypt.check_password_hash(user.passwordHashed, password):
        flask.g.user = username
        return True

    return False


def gitCommand(repo, data, *args):
    if not os.path.isdir(repo):
        raise FileNotFoundError("Repo not found")
    env = os.environ.copy()

    command = ["git", *args]
    print("RUNNING GIT COMMAND")
    print(" ".join(command))
    proc = subprocess.Popen(" ".join(command), cwd=repo, env=env, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
    print(command)

    if data:
        proc.stdin.write(data)

    out, err = proc.communicate()
    return out


@app.route("/git/<username>/<repository>/git-upload-pack", methods=["POST"])
@auth.login_required
def gitUploadPack(username, repository):
    serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository, ".git")
    text = gitCommand(serverRepoLocation, flask.request.data, "upload-pack", "--stateless-rpc", ".")

    return flask.Response(text, content_type="application/x-git-upload-pack-result")


@app.route("/git/<username>/<repository>/git-receive-pack", methods=["POST"])
@auth.login_required
def gitReceivePack(username, repository):
    serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository, ".git")
    text = gitCommand(serverRepoLocation, flask.request.data, "receive-pack", "--stateless-rpc", ".")

    return flask.Response(text, content_type="application/x-git-receive-pack-result")


@app.route("/git/<username>/<repository>/info/refs", methods=["GET"])
@auth.login_required
def gitInfoRefs(username, repository):
    serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository, ".git")
    service = flask.request.args.get("service")

    if service.startswith("git"):
        service = service[4:]

    print(service)

    serviceLine = f"# service=git-{service}\n"
    serviceLine = (f"{len(serviceLine) + 4:04x}" + serviceLine).encode()

    if service == "upload-pack":
        text = serviceLine + b"0000" + gitCommand(serverRepoLocation, None, "upload-pack", "--stateless-rpc", "--advertise-refs", "--http-backend-info-refs", ".")
    elif service == "receive-pack":
        text = serviceLine + b"0000" + gitCommand(serverRepoLocation, None, "receive-pack", "--http-backend-info-refs", ".")

    response = flask.Response(text, content_type=f"application/x-git-{service}-advertisement")
    response.headers["Cache-Control"] = "no-cache"

    return response

