'''
Get artifact from an artifact server.

The server should present a directory structure over http/https. The leaf
directories should contain a file called `last_good_build.properties`
(typically generated by jenkins) containing a line like:

    ARTIFACT=subdir/buz.tar.gz

which is then resolved as the latest version available for this directory.
'''
import os
import sys
import tasktool.utils as utils


def verify(config):
    if config.get('url') is None:
        raise Exception("No 'url' specified")


def resolve_latest(config):
    assert(config['type'] == 'artifact_server')
    url = config['url']
    if not url.endswith('/'):
        url += '/'
    latest_info_file = config.get('latest_info_file',
                                  'last_good_build.properties')
    latest_url = url + latest_info_file
    props = utils.check_output(['curl', '-s', latest_url])

    res = None
    latest_key = config.pop('latest_key', 'ARTIFACT')
    for line in props.split('\n'):
        line = line.strip()
        if line.startswith('%s=' % latest_key):
            res = line[len(latest_key)+1:]
            break

    # We usually have something like, try to resolve this to a single URL
    #   URL=https://myserver.com/mybuild/
    #   ARTIFACT=mybuild/blabla.tar.gz
    dirname = os.path.dirname(res) + "/"
    full_url = url
    if full_url.endswith(dirname):
        full_url = full_url[:-len(dirname)]
    full_url += res
    config['url'] = full_url
    config['type'] = 'url'


def get_artifact(config, dest_dir):
    raise Exception("A2 artifact not resolved to URL?!?")


def repro_arg(config, dest_dir):
    raise Exception("A2 artifact not resolved to URL?!?")
