#
# Copyright (c) SAS Institute Inc
#

from urlparse import urljoin
import hashlib
import json
import logging
import os

from conary.lib import util

from pymaven.client import MavenClient
import requests

from .errors import MissingArtifactError
from .pompackage import PomPackage


__all__ = ('Client', 'PomPackage')

log = logging.getLogger(__name__)

# Turn down the logging level on requeests
requests_logger = logging.getLogger('requests.packages.urllib3.connectionpool')
requests_logger.setLevel(logging.WARN)


def detail(func):
    def wrapper(*args, **kwargs):
        info = kwargs.pop('info', False)
        properties = kwargs.pop('properties', False)

        detail = []
        if info:
            detail.append('info')
        elif properties:
            detail.append('properties')
        if detail:
            kwargs.setdefault(
                'headers', {})['x-result-detail'] = ','.join(detail)
        return func(*args, **kwargs)
    return wrapper


def repos(func):
    def wrapper(*args, **kwargs):
        repos = kwargs.pop('repos', None)
        if repos:
            if isinstance(repos, (str, unicode)):
                repos = [repos]
            kwargs.setdefault('params', {})['repos'] = ','.join(repos)
        return func(*args, **kwargs)
    return wrapper


class Client(MavenClient):
    """
    Client for talking to artfactory api
    """

    def __init__(self, cfg, headers=None):
        """
        Create a client from a updatebot config object.

        If there are default headers you want used for every request, pass in
        a dictionary:
            Client("http://example.com,
                headers={'my-default-header': 'foo'})

        :param UpdateBotConfig cfg: cfg object to use for configuring the client
        :param dict headers: dictionary of headers to use for all requests
        """
        self._cfg = cfg
        self._url = cfg.repositoryUrl
        if not self._url.endswith('/'):
            self._url = self._url + '/'
        super(Client, self).__init__(
            *[urljoin(self._url, repo) for repo in cfg.repositoryPaths])

    def _search(self, path, **kwargs):
        log.debug("search(%s, kwargs=%s)", path, kwargs)
        if 'auth' not in kwargs:
            kwargs['auth'] = self._cfg.artifactoryUser.find(
                self._cfg.repositoryUrl)

        repo = self._repos[0]
        uri = urljoin("api/search/", path)
        res = repo._get(urljoin(self._url, uri), **kwargs)
        urls = [r['uri'] for r in res.json.get('results', [])]

        for url in urls:
            res = repo._get(url)
            if res.status_code == requests.codes.not_found:
                log.warn('error fetching %s', url)
                continue
            yield res.json

    def constructPath(self, groupId, artifactId, version=None,
                      artifactName=None, extension='pom', relative=False):
        """Construct a maven 2 path

        :param groupId: group name
        :type groupId: string
        :param artifactId: artifact name
        :type artifactId: string
        :param version: (None) version of artifact
        :type version: string
        :param artifactName: (None) artifact name if not the artifactId
        :type artifactName: string
        :param extension: (pom) file extention of artifact
        :type extension: string
        :param relative: (False) generate a relative path
        :type relative: bool
        """
        path = '/{0}/{1}'
        if relative:
            path = path[1:]

        if version:
            path += '/{2}'

        if artifactName:
            path += '/{3}.{4}'
        else:
            path += '/{1}-{2}.{4}'

        path = path.format(
            groupId.replace('.', '/'),
            artifactId,
            version,
            artifactName,
            extension,
            )
        return path

    def checkPath(self, path, relative=False):
        client = self._repos[0]
        for repo in self._cfg.repositoryPaths: