#!/bin/python3

import sys, os, subprocess, shutil, pysftp


def check_refs():
    for line in sys.stdin:
        old_hash, new_hash, ref = line.strip().split(' ')
        if ref == "refs/heads/master":
            return (True, old_hash, new_hash)
    return (False, None, None)


def make_temp_dirs():
    try:
        os.mkdir("/tmp/website_checkout")
    except FileExistsError:
        shutil.rmtree("/tmp/website_checkout")
        os.mkdir("/tmp/website_checkout")
    try:
        os.mkdir("/tmp/website_build")
    except FileExistsError:
        shutil.rmtree("/tmp/website_build")
        os.mkdir("/tmp/website_build")


def git_checkout():
    subprocess.run(
        ["git", "--git-dir=.", "--work-tree=/tmp/website_checkout", "checkout", "master", "."]
    ).check_returncode()


def jekyll_build():
    os.environ["GEM_HOME"] = "/home/git/gems"
    os.environ["PATH"] = "/home/git/gems/bin:" + os.environ["PATH"]
    os.environ["BUNDLE_GEMFILE"] = "/tmp/website_checkout/Gemfile"
    subprocess.run(["bundle", "install"]).check_returncode()
    subprocess.run(
        ["bundle", "exec", "jekyll", "build", "-s", "/tmp/website_checkout", "-d", "/tmp/website_build"]
    ).check_returncode()


def rmdir(sftp: pysftp.Connection, path: str):
    if not sftp.exists(path):
        return None
    for p in sftp.listdir(path):
        if sftp.isdir(f"{path}/{p}"):
            rmdir(sftp, f"{path}/{p}")
        else:
            sftp.remove(f"{path}/{p}")
    sftp.rmdir(path)


def get_sftp_password():
    password_file = open("/home/git/sftp_pass", "r")
    password = password_file.read().strip()
    password_file.close()
    return password


def deploy(password: str):
    with pysftp.Connection("sftp_host_domain", username="sftp_user", password=password) as sftp:
        rmdir(sftp, "/home/sftp_user/www")
        sftp.mkdir("/home/sftp_user/www")
        sftp.put_r("/tmp/website_build", "/home/sftp_user/www")


def cleanup():
    shutil.rmtree("/tmp/website_build")
    shutil.rmtree("/tmp/website_checkout")


def main():
    should_update, old_hash, new_hash = check_refs()
    if not should_update:
        print("Build and Deploy: nothing to do")
        return None
    print(f"Updates master from {old_hash} to {new_hash}, rebuilding Jekyll")
    print("Making temporary dirs")
    make_temp_dirs()
    print("Checking out master")
    git_checkout()
    print("Building Jekyll")
    jekyll_build()
    print("Deploying via SFTP")
    deploy(get_sftp_password())
    print("Cleaing up temporary dirs")
    cleanup()
    print("Build and Deploy complete!")


if __name__ == "__main__":
    main()
