#!/usr/bin/env python3
import hashlib
import json
from argparse import ArgumentParser
from glob import glob
from sys import argv

from vang.artifactory import api
from vang.artifactory.utils import get_artifact_base_uri, get_pom_path
from vang.maven.pom import get_pom_info


def read_file(file_path):  # pragma: no cover
    with open(file_path, 'rb') as f:
        return f.read()


def get_checksums(the_bytes):
    return hashlib.md5(the_bytes).hexdigest(), hashlib.sha1(
        the_bytes).hexdigest(), hashlib.sha256(the_bytes).hexdigest()


def get_checksum_headers(md5, sha1, sha256):
    return {
        'X-Checksum-Md5': md5,
        'X-Checksum-Sha1': sha1,
        # sha256 Not yet supported...
        'X-Checksum-Sha256': sha256
    }


def get_pom_publish_name(pom_path, artifact_id, version):
    pom_name = pom_path.split('/')[-1]
    return pom_name if pom_name.split(
        '.')[-1] == 'pom' else f'{artifact_id}-{version}.pom'


def get_publish_data(artifact_base_uri, path, name):
    content = read_file(path)
    md5, sha1, sha256 = get_checksums(content)
    return {
        'content': content,
        'checksum_headers': get_checksum_headers(md5, sha1, sha256),
        'uri': f'{artifact_base_uri}/{name}'
    }


def publish_maven_artifact(repository, pom_dirs):
    for pom_dir in pom_dirs:
        pom_info = get_pom_info(get_pom_path(pom_dir))
        base_uri = get_artifact_base_uri(repository, pom_info['group_id'],
                                         pom_info['artifact_id'],
                                         pom_info['version'])

        publish_data = [get_publish_data(base_uri, pom_info['pom_path'],
                                         get_pom_publish_name(pom_info['pom_path'],
                                                              pom_info['artifact_id'],
                                                              pom_info['version']))] + \
                       [get_publish_data(base_uri, path, path.split('/')[-1])
                        for path in
                        glob(f'{pom_dir}/**/*.jar', recursive=True) +
                        glob(f'{pom_dir}/**/*.war', recursive=True)]

        yield [
            api.call(pd['uri'], pd['checksum_headers'], pd['content'], 'PUT')
            for pd in publish_data
        ]


def main(repository, dirs):
    for response in publish_maven_artifact(repository, dirs):
        print(json.dumps(json.loads(str(response).replace("'", '"')), indent=2))


def parse_args(args):
    parser = ArgumentParser(description='Publish maven artifact to Artifactory')
    parser.add_argument(
        'repository', help='Artifactory repository, e.g. z-release')
    parser.add_argument(
        '-d',
        '--dirs',
        nargs='*',
        default=['.'],
        help='Maven pom directories to extract artifact information from')
    return parser.parse_args(args)


if __name__ == '__main__':  # pragma: no cover
    main(**parse_args(argv[1:]).__dict__)
