"""Build metadata for a project using PEP 517 hooks.
"""
import argparse
import functools
import logging
import os
import shutil
import tempfile

try:
    import importlib.metadata as imp_meta
except ImportError:
    import importlib_metadata as imp_meta

try:
    from zipfile import Path
except ImportError:
    from zipp import Path

from .build import compat_system, load_system, validate_system
from .dirtools import dir_to_zipfile
from .envbuild import BuildEnvironment
from .wrappers import Pep517HookCaller, quiet_subprocess_runner

log = logging.getLogger(__name__)


def _prep_meta(hooks, env, dest):
    reqs = hooks.get_requires_for_build_wheel({})
    log.info('Got build requires: %s', reqs)

    env.pip_install(reqs)
    log.info('Installed dynamic build dependencies')

    with tempfile.TemporaryDirectory() as td:
        log.info('Trying to build metadata in %s', td)
        filename = hooks.prepare_metadata_for_build_wheel(td, {})
        source = os.path.join(td, filename)
        shutil.move(source, os.path.join(dest, os.path.basename(filename)))


def build(source_dir='.', dest=None, system=None):
    system = system or load_system(source_dir)
    dest = os.path.join(source_dir, dest or 'dist')
    os.makedirs(dest, exist_ok=True)
    validate_system(system)
    hooks = Pep517HookCaller(
        source_dir, system['build-backend'], system.get('backend-path')
    )

    with hooks.subprocess_runner(quiet_subprocess_runner):
        with BuildEnvironment() as env:
            env.pip_install(system['requires'])
            _prep_meta(hooks, env, dest)


def build_as_zip(builder=build):
    with tempfile.TemporaryDirectory() as out_dir:
        builder(dest=out_dir)
        return dir_to_zipfile(out_dir)


def load(root):
    """
    Given a source directory (root) of a package,
    return an importlib.metadata.Distribution object
    with metadata build from that package.
    """
    root = os.path.expanduser(root)
    system = compat_system(root)
    builder = functools.partial(build, source_dir=root, system=system)
    path = Path(build_as_zip(builder))
    return imp_meta.PathDistribution(path)


parser = argparse.ArgumentParser()
parser.add_argument(
    'source_dir',
    help="A directory containing pyproject.toml",
)
parser.add_argument(
    '--out-dir', '-o',
    help="Destination in which to save the builds relative to source dir",
)


def main():
    args = parser.parse_args()
    build(args.source_dir, args.out_dir)


if __name__ == '__main__':
    main()
