from pathlib import Path
import json
from subprocess import run, PIPE
from shlex import split as X
from ocrd_utils import pushd_popd, getLogger
import requests as R

LOG = getLogger('kwalitee.repo')


class Repo():

    def __init__(self, config, url, official=False, compliant_cli=False):
        self.url = url
        self.config = config
        self.name = Path(url).name
        self.official = official
        self.compliant_cli = compliant_cli
        self.path = Path(self.config['repodir'], self.name)

    def __str__(self):
        return '<Repo %s @ %s>' % (self.url, self.path)

    def is_cloned(self):
        return self.path.is_dir()

    def pull(self):
        with pushd_popd(self.path):
            self._run('git pull origin master')

    def clone(self):
        if self.is_cloned():
            LOG.debug("Already cloned: %s" % self.path)
            return
        with pushd_popd(self.config['repodir']):
            LOG.debug("Cloning %s" % self.url)
            result = self._run('git clone --depth 1 "%s"' % self.url)
            LOG.debug("Result: %s" % result)


    def get_git_stats(self):
        ret = {}
        LOG.info("  Fetching git info")
        with pushd_popd(self.path):
            ret['number_of_commits'] = self._run('git rev-list HEAD --count').stdout
            ret['last_commit'] = self._run(r'git log -1 --format=%cd ').stdout
            ret['url'] = self._run('git config --get remote.origin.url').stdout
            ret['latest_tag'] = self._run('git describe --abbrev=0 --tags').stdout
        return ret

    def get_file_contents(self):
        ret = {}
        LOG.info("  Getting file contents")
        with pushd_popd(self.path):
            for path in [Path(x) for x in ['ocrd-tool.json', 'Dockerfile', 'README.md', 'setup.py']]:
                if path.is_file():
                    with path.open() as f:
                        ret[path.name] = f.read()
                else:
                    ret[path.name] = None
        return ret

    def get_python_info(self):
        ret = {}
        with pushd_popd(self.path):
            ret['url'] = self._run('python3 setup.py --url').stdout
            ret['name'] = self._run('python3 setup.py --name').stdout
            ret['author'] = self._run('python3 setup.py --author').stdout
            ret['author-email'] = self._run('python3 setup.py --author-email').stdout
        LOG.info("  Fetching pypi info")
        response = R.get('https://pypi.python.org/pypi/%s/json' % ret['name'])
        ret['pypi'] = json.loads(response.text) if response.status_code == 200 else None
        return ret

    def to_json(self):
        desc = {}
        desc['url'] = self.url
        desc['official'] = self.official
        desc['compliant_cli'] = self.compliant_cli
        desc['org_plus_name'] = '/'.join(self.url.split('/')[-2:])
        desc['name'] = self.name
        desc['files'] = self.get_file_contents()
        if desc['files']['ocrd-tool.json']:
            desc['ocrd_tool'] = json.loads(desc['files']['ocrd-tool.json'])
            with pushd_popd(self.path):
                desc['ocrd_tool_validate'] = self._run('ocrd ocrd-tool ocrd-tool.json validate').stdout
        else:
            desc['ocrd_tool'] = ''
            desc['ocrd_tool_validate'] = 'NO ocrd-tool.json'
        desc['git'] = self.get_git_stats()
        if desc['files']['setup.py']:
            desc['python'] = self.get_python_info()
        return desc

    def _run(self, cmd, **kwargs):
        result = run(X(cmd), stdout=PIPE, encoding='utf-8', **kwargs)
        if result.stdout:
            result.stdout = result.stdout.strip()
        return result