#!/usr/bin/env python

import os
import sys

from optparse import OptionParser

import requests

from slingrpm.utils import hash_file
from slingrpm.utils import iam
from slingrpm.repo_config import parse_public_config


def vararg_callback(option, opt_str, value, parser):
     assert value is None
     value = []

     def floatable(str):
         try:
             float(str)
             return True
         except ValueError:
             return False

     for arg in parser.rargs:
         # stop on --foo like options
         if arg[:2] == "--" and len(arg) > 2:
             break
         # stop on -a, but not on -3 or -3.0
         if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
             break
         value.append(arg)

     del parser.rargs[:len(value)]
     setattr(parser.values, option.dest, value)

parser = OptionParser()
parser.add_option('-f', '--file',
                  help="file(s) to upload",
                  default=None, action="callback", callback=vararg_callback,
                  dest="rpm_files")
parser.add_option('-r', '--repo_dir',
                  help="repostiory to update",
                  default=None, action="store", type="string",
                  dest="repo_dir")
parser.add_option('-u', '--slingrpm-uri',
                  help="URI of the slingrpm endpoint",
                  default=None, action="store", type="string",
                  dest="slingrpm_uri")
parser.add_option('-c', '--repo-config',
                  help="URI of slingrpm config",
                  default=None, action="store", type="string",
                  dest="slingrpm_config_uri")
parser.add_option('-i', '--iam-auth',
                  help="use IAM authentication, requires AWS creds",
                  action="store_true", dest="iam_auth")

(options, args) = parser.parse_args()

_errors = []

CONFIG_URI = True
CONFIG_PAIR = True

if options.rpm_files is None:
    _errors.append('RPM_FILE required')
if options.slingrpm_config_uri is None:
    CONFIG_URI = False
if options.repo_dir is None and options.slingrpm_uri is None:
    CONFIG_PAIR = False
if not CONFIG_URI and not CONFIG_PAIR:
    _errors.append('One of SLINGRPM_CONFIG_URI or REPO_DIR and SLINGRPM_URI'
                    ' is required')
if CONFIG_PAIR:
    if options.repo_dir is None:
        _errors.append('REPO_DIR required')
    if options.slingrpm_uri is None:
        _errors.append('SLINGRPM_URI required')
else:
    try:
        r = requests.get(options.slingrpm_config_uri)
        public_config = parse_public_config(r.text)
        options.repo_dir = public_config.get('public', 'repository_dir')
        options.slingrpm_uri = public_config.get('public', 'submission_url')
    except Exception:
        _errors.append('Unable to load config from %s' %
                       (options.slingrpm_config_uri))

if len(_errors) > 0:
    parser.print_help()
    for error in _errors:
        print error
    sys.exit(1)

headers = {}

if options.iam_auth:
    access_key = os.environ.get('AWS_ACCESS_KEY_ID')
    secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')
    if access_key is None or secret_key is None:
        print 'No AWS creds are available.'
        sys.exit(1)
    auth_query_url = iam.generate_get_user_query(access_key, secret_key)
    headers['X-IAMPassthroughAuth-Query'] = auth_query_url

for rpm_file in options.rpm_files:
    files = {'package': open(rpm_file, 'rb')}
    data = {'repository': options.repo_dir,
            'md5hash': hash_file(open(rpm_file, 'rb'))}
    r = requests.post(options.slingrpm_uri, files=files, data=data, headers=headers)
    print r.text
