import hashlib
import http
import io
import os.path
import stat
import sys
import tarfile
import urllib.request
import zipfile
from distutils.command.build import build as orig_build
from distutils.core import Command
from typing import Tuple
from setuptools import setup
from setuptools.command.install import install as orig_install
BIN = "committed"
VERSION = '0.2.4'
POSTFIX_SHA256 = {
    'linux': (
        'x86_64-unknown-linux-musl.tar.gz',
        '',      ),
    'darwin': (
        'x86_64-apple-darwin.tar.gz',
        '',      ),
    'win32': (
        'x86_64-pc-windows-msvc.zip',
        '',      ),
}
PY_VERSION = '1'
def get_download_url() -> Tuple[str, str]:
    postfix, sha256 = POSTFIX_SHA256[sys.platform]
    url = (
        f'https://github.com/crate-ci/{BIN}/releases/download/'
        f'v{VERSION}/{BIN}-v{VERSION}-{postfix}'
    )
    return url, sha256
def download(url: str, sha256: str) -> bytes:
    with urllib.request.urlopen(url) as resp:
        code = resp.getcode()
        if code != http.HTTPStatus.OK:
            raise ValueError(f'HTTP failure. Code: {code}')
        data = resp.read()
    if not sha256:
        return data
    checksum = hashlib.sha256(data).hexdigest()
    if checksum != sha256:
        raise ValueError(f'sha256 mismatch, expected {sha256}, got {checksum}')
    return data
def extract(url: str, data: bytes) -> bytes:
    with io.BytesIO(data) as bio:
        if '.tar.' in url:
            with tarfile.open(fileobj=bio) as tarf:
                for info in tarf.getmembers():
                    if info.isfile() and info.name.endswith(BIN):
                        return tarf.extractfile(info).read()
        elif url.endswith('.zip'):
            with zipfile.ZipFile(bio) as zipf:
                for info in zipf.infolist():
                    if info.filename.endswith('.exe'):
                        return zipf.read(info.filename)
    raise AssertionError(f'unreachable {url}')
def save_executable(data: bytes, base_dir: str):
    suffix = ".exe" if sys.platform == 'win32' else ""
    exe = f"{BIN}{suffix}"
    output_path = os.path.join(base_dir, exe)
    os.makedirs(base_dir)
    with open(output_path, 'wb') as fp:
        fp.write(data)
            mode = os.stat(output_path).st_mode
    mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
    os.chmod(output_path, mode)
class build(orig_build):
    sub_commands = orig_build.sub_commands + [('fetch_binaries', None)]
class install(orig_install):
    sub_commands = orig_install.sub_commands + [('install_bin', None)]
class fetch_binaries(Command):
    build_temp = None
    def initialize_options(self):
        pass
    def finalize_options(self):
        self.set_undefined_options('build', ('build_temp', 'build_temp'))
    def run(self):
                url, sha256 = get_download_url()
        archive = download(url, sha256)
        data = extract(url, archive)
        save_executable(data, self.build_temp)
class install_bin(Command):
    description = 'install the executable'
    outfiles = ()
    build_dir = install_dir = None
    def initialize_options(self):
        pass
    def finalize_options(self):
                self.set_undefined_options('build', ('build_temp', 'build_dir'))
        self.set_undefined_options(
            'install', ('install_scripts', 'install_dir'),
        )
    def run(self):
        self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
    def get_outputs(self):
        return self.outfiles
command_overrides = {
    'install': install,
    'install_bin': install_bin,
    'build': build,
    'fetch_binaries': fetch_binaries,
}
try:
    from wheel.bdist_wheel import bdist_wheel as orig_bdist_wheel
except ImportError:
    pass
else:
    class bdist_wheel(orig_bdist_wheel):
        def finalize_options(self):
            orig_bdist_wheel.finalize_options(self)
                        self.root_is_pure = False
        def get_tag(self):
            _, _, plat = orig_bdist_wheel.get_tag(self)
                        return 'py2.py3', 'none', plat
    command_overrides['bdist_wheel'] = bdist_wheel
setup(version=f'{VERSION}.{PY_VERSION}', cmdclass=command_overrides)