import json
import re
import sys

import requests  # type:ignore

try:
    from packaging.version import Version, parse
except ImportError:
    from pip._vendor.packaging.version import Version, parse  # type:ignore


PATTERN = re.compile(r'\[(.*?)\]')
VER_PAT = re.compile(r'^\d\.\d\.\d$')

URL_PATTERN = 'https://pypi.python.org/pypi/{package}/json'


def get_latest_version_from_PyPI(
        package: str,
        url_pattern: str = URL_PATTERN,
) -> Version:
    """Return version of package on pypi.python.org using json."""
    req = requests.get(url_pattern.format(package=package))
    version = parse('0')
    if req.status_code == requests.codes.ok:
        j = json.loads(req.text.encode(req.encoding))
        releases = j.get('releases', [])
        for release in releases:
            ver = parse(release)
            if not ver.is_prerelease:
                version = max(version, ver)

    return version


def should_fail_version_check(
        mode: str,
        local_latest_ver: Version,
        pypi_latest_ver: Version,
) -> bool:
    if mode == 'branch':
        return local_latest_ver < pypi_latest_ver

    if mode == 'main':
        return local_latest_ver <= pypi_latest_ver

    raise RuntimeError('Internal error; please contact the authors')


def main() -> int:
    mode = sys.argv[1] if len(sys.argv) > 1 else 'branch'

    with open('CHANGELOG.md') as fp:
        lines = fp.readlines()

    if len(lines) == 0:
        print('Empty CHANGELOG.md file')
        return 1

    print('Contents of CHANGELOG.md (up to the latest local version):\n')
    if lines[0] != '# Change Log\n':
        print(f'Unexpected first line in CHANGELOG.md: {lines[0]}')
        return 1

    for line in lines[1:]:
        print(line.rstrip())
        if line.startswith('##'):
            if line == '## [Unreleased]\n':
                continue

            match = PATTERN.search(line)
            version = match.group(1)  # type:ignore
            if not VER_PAT.match(version):
                print(f'Invalid version: {version}')
                return 1

            break

    latest_version_on_PyPI = get_latest_version_from_PyPI('cercis')

    if should_fail_version_check(mode, parse(version), latest_version_on_PyPI):
        print(
            f'Newest local version ({version}) must be higher than the'
            f' latest version on PyPI ({latest_version_on_PyPI})'
        )
        return 1

    return 0


if __name__ == '__main__':
    raise SystemExit(main())
