#!/usr/bin/env python3

import requests
import yaml
import os
import sys
import subprocess


def find_chart_yaml(dir):
    """
    try to find Chart.yaml inside a directory
    """
    dpath = os.path.normpath(dir)
    candidate = dpath + "/Chart.yaml"
    if os.path.isfile(candidate):
        return candidate
    else:
        return None


def get_local_chart_data(path):
    f = find_chart_yaml(path)
    if f:
        data_local = read_yaml_file(f)
        return data_local
    else:
        print("error finding Chart.yaml in " + path)
        sys.exit(127)


def read_yaml_file(file):
    y = yaml.safe_load(open(file, "r"))
    return(y)


def read_remote_index(repo_url):
    """
    read and load /index.yaml from a remote chart repo
    repo_url should look like = "https://charts.demo.com"
    returns the full index.yaml after loading
    """
    url = repo_url + "/index.yaml"

    r = requests.get(url)

    # NOTE.. I've not tested this against anon repos now
    try:
        return yaml.safe_load(r.text)
    except:
        print("error getting yaml from {}".format(url))
        sys.exit(127)


def subprocess_caller(
        cmd,
        timeout=False,
        extra_env=None
        ):
    """
    launches a subprocess, returns True/False based on return-code
    :param cmd:
    :param timeout:     timeout if running the command takes longer than this (s)
    :return:
    """
    kwargs = {}
    if timeout is not False:
        kwargs['timeout'] = int(timeout)
    if extra_env is None:
        extra_env = {}
    kwargs['shell'] = True
    kwargs['universal_newlines'] = True
    try:
        subprocess.check_call(cmd, **kwargs)
        return True
    except:
        return False


def do_push(chart, url):
    cmd = "helm push {} {}".format(chart, url)
    subprocess_caller(cmd=cmd)


if __name__ == '__main__':

    chart = sys.argv[1]
    repo_url = sys.argv[2]
    local = get_local_chart_data(chart)
    local_name = local['name']
    local_version = local['version']
    print("{}:{} (local) chart".format(local_name, local_version))

    remote = read_remote_index(repo_url)
    if not remote['entries']:
        print("Something went wrong talking the the chart repo")
        print("remote data:" + remote)
        sys.exit(2)

    entries = remote['entries']
    if local_name in entries:
        """
        this chart exists remotely, lets check if there is a matching version remotely
        """
        print("  " + local_name + " is known in remote repo..")
        for i in remote['entries'][local_name]:
            if local_version == i['version']:
                print("  {}:{} already exists remotely".format(local_name, local_version))
                sys.exit(0)
        do_push(chart, repo_url)


    else:
        """
        this chart doesn't exist remotely.. push it
        """
        print("  {}:{} does not exist remotely.. push it".format(
            local_name, local_version))
        do_push(chart, repo_url)



