# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import base64
import collections
import hashlib
import os
import os.path
import re
import sys
import zipfile


def commonpath(path1, path2):
    ret = []
    for a, b in zip(path1.split(os.path.sep), path2.split(os.path.sep)):
        if a != b:
            break
        ret.append(a)
    return os.path.sep.join(ret)


def escape_filename_segment(segment):
    """Escapes a filename segment per https://www.python.org/dev/peps/pep-0427/#escaping-and-unicode"""
    return re.sub(r"[^\w\d.]+", "_", segment, re.UNICODE)


class WheelMaker(object):
    def __init__(self, name, version, build_tag, python_tag, abi, platform,
                 outfile=None, strip_path_prefixes=None):
        self._name = name
        self._version = version
        self._build_tag = build_tag
        self._python_tag = python_tag
        self._abi = abi
        self._platform = platform
        self._outfile = outfile
        self._strip_path_prefixes = strip_path_prefixes if strip_path_prefixes is not None else []

        self._distinfo_dir = (escape_filename_segment(self._name) + '-' +
                              escape_filename_segment(self._version) +
                              '.dist-info/')
        self._zipfile = None
        self._record = []

    def __enter__(self):
        self._zipfile = zipfile.ZipFile(self.filename(), mode="w",
                                        compression=zipfile.ZIP_DEFLATED)
        return self

    def __exit__(self, type, value, traceback):
        self._zipfile.close()
        self._zipfile = None

    def filename(self):
        if self._outfile:
            return self._outfile
        components = [self._name, self._version]
        if self._build_tag:
            components.append(self._build_tag)
        components += [self._python_tag, self._abi, self._platform]
        return '-'.join(components) + '.whl'

    def disttags(self):
        return ['-'.join([self._python_tag, self._abi, self._platform])]

    def distinfo_path(self, basename):
        return self._distinfo_dir + basename

    def _serialize_digest(self, hash):
        # https://www.python.org/dev/peps/pep-0376/#record
        # "base64.urlsafe_b64encode(digest) with trailing = removed"
        digest = base64.urlsafe_b64encode(hash.digest())
        digest = b'sha256=' + digest.rstrip(b'=')
        return digest

    def add_string(self, filename, contents):
        """Add given 'contents' as filename to the distribution."""
        if sys.version_info[0] > 2 and isinstance(contents, str):
            contents = contents.encode('utf-8', 'surrogateescape')
        self._zipfile.writestr(filename, contents)
        hash = hashlib.sha256()
        hash.update(contents)
        self._add_to_record(filename, self._serialize_digest(hash),
                            len(contents))

    def add_file(self, package_filename, real_filename):
        """Add given file to the distribution."""

        def arcname_from(name):
            # Always use unix path separators.
            normalized_arcname = name.replace(os.path.sep, '/')
            for prefix in self._strip_path_prefixes:
                if normalized_arcname.startswith(prefix):
                    return normalized_arcname[len(prefix):]

            return normalized_arcname

        if os.path.isdir(real_filename):
            directory_contents = os.listdir(real_filename)
            for file_ in directory_contents:
                self.add_file("{}/{}".format(package_filename, file_),
                              "{}/{}".format(real_filename, file_))
            return

        arcname = arcname_from(package_filename)

        self._zipfile.write(real_filename, arcname=arcname)
        # Find the hash and length
        hash = hashlib.sha256()
        size = 0
        with open(real_filename, 'rb') as f:
            while True:
                block = f.read(2 ** 20)
                if not block:
                    break
                hash.update(block)
                size += len(block)
        self._add_to_record(arcname, self._serialize_digest(hash), size)

    def add_wheelfile(self):
        """Write WHEEL file to the distribution"""
        # TODO(pstradomski): Support non-purelib wheels.
        wheel_contents = """\
Wheel-Version: 1.0
Generator: bazel-wheelmaker 1.0
Root-Is-Purelib: {}
""".format("true" if self._platform == "any" else "false")
        for tag in self.disttags():
            wheel_contents += "Tag: %s\n" % tag
        self.add_string(self.distinfo_path('WHEEL'), wheel_contents)

    def add_metadata(self, extra_headers, description, classifiers, python_requires,
                     requires, extra_requires):
        """Write METADATA file to the distribution."""
        # https://www.python.org/dev/peps/pep-0566/
        # https://packaging.python.org/specifications/core-metadata/
        metadata = []
        metadata.append("Metadata-Version: 2.1")
        metadata.append("Name: %s" % self._name)
        metadata.append("Version: %s" % self._version)
        metadata.extend(extra_headers)
        for classifier in classifiers:
            metadata.append("Classifier: %s" % classifier)
        if python_requires:
            metadata.append("Requires-Python: %s" % python_requires)
        for requirement in requires:
            metadata.append("Requires-Dist: %s" % requirement)

        extra_requires = sorted(extra_requires.items())
        for option, option_requires in extra_requires:
            metadata.append("Provides-Extra: %s" % option)
            for requirement in option_requires:
                metadata.append(
                    "Requires-Dist: %s; extra == '%s'" % (requirement, option))

        metadata = '\n'.join(metadata) + '\n\n'
        # setuptools seems to insert UNKNOWN as description when none is
        # provided.
        metadata += description if description else "UNKNOWN"
        metadata += "\n"
        self.add_string(self.distinfo_path('METADATA'), metadata)

    def add_recordfile(self):
        """Write RECORD file to the distribution."""
        record_path = self.distinfo_path('RECORD')
        entries = self._record + [(record_path, b'', b'')]
        entries.sort()
        contents = b''
        for filename, digest, size in entries:
            if sys.version_info[0] > 2 and isinstance(filename, str):
                filename = filename.encode('utf-8', 'surrogateescape')
            contents += b'%s,%s,%s\n' % (filename, digest, size)
        self.add_string(record_path, contents)

    def _add_to_record(self, filename, hash, size):
        size = str(size).encode('ascii')
        self._record.append((filename, hash, size))


def get_files_to_package(input_files):
    """Find files to be added to the distribution.

    input_files: list of pairs (package_path, real_path)
    """
    files = {}
    for package_path, real_path in input_files:
        files[package_path] = real_path
    return files


def main():
    parser = argparse.ArgumentParser(description='Builds a python wheel')
    metadata_group = parser.add_argument_group(
        "Wheel name, version and platform")
    metadata_group.add_argument('--name', required=True,
                                type=str,
                                help="Name of the distribution")
    metadata_group.add_argument('--version', required=True,
                                type=str,
                                help="Version of the distribution")
    metadata_group.add_argument('--build_tag', type=str, default='',
                                help="Optional build tag for the distribution")
    metadata_group.add_argument('--python_tag', type=str, default='py3',
                                help="Python version, e.g. 'py2' or 'py3'")
    metadata_group.add_argument('--abi', type=str, default='none')
    metadata_group.add_argument('--platform', type=str, default='any',
                                help="Target platform. ")

    output_group = parser.add_argument_group("Output file location")
    output_group.add_argument('--out', type=str, default=None,
                              help="Override name of ouptut file")

    output_group.add_argument('--strip_path_prefix',
                              type=str,
                              action="append",
                              default=[],
                              help="Path prefix to be stripped from input package files' path. "
                                   "Can be supplied multiple times. "
                                   "Evaluated in order."
                              )

    wheel_group = parser.add_argument_group("Wheel metadata")
    wheel_group.add_argument(
        '--header', action='append',
        help="Additional headers to be embedded in the package metadata. "
             "Can be supplied multiple times.")
    wheel_group.add_argument('--classifier', action='append',
                             help="Classifiers to embed in package metadata. "
                                  "Can be supplied multiple times")
    wheel_group.add_argument('--python_requires',
                             help="Version of python that the wheel will work with")
    wheel_group.add_argument('--description_file',
                             help="Path to the file with package description")
    wheel_group.add_argument('--entry_points_file',
                             help="Path to a correctly-formatted entry_points.txt file")

    contents_group = parser.add_argument_group("Wheel contents")
    contents_group.add_argument(
        '--input_file', action='append',
        help="'package_path;real_path' pairs listing "
             "files to be included in the wheel. "
             "Can be supplied multiple times.")
    contents_group.add_argument(
        '--input_file_list', action='append',
        help='A file that has all the input files defined as a list to avoid the long command'
    )

    requirements_group = parser.add_argument_group("Package requirements")
    requirements_group.add_argument(
        '--requires', type=str, action='append',
        help="List of package requirements. Can be supplied multiple times.")
    requirements_group.add_argument(
        '--extra_requires', type=str, action='append',
        help="List of optional requirements in a 'requirement;option name'. "
             "Can be supplied multiple times.")
    arguments = parser.parse_args(sys.argv[1:])

    if arguments.input_file:
        input_files = [i.split(';') for i in arguments.input_file]
    else:
        input_files = []

    if arguments.input_file_list:
        for input_file in arguments.input_file_list:
            with open(input_file) as _file:
                input_file_list = _file.read().splitlines()
            for _input_file in input_file_list:
                input_files.append(_input_file.split(';'))

    all_files = get_files_to_package(input_files)
    # Sort the files for reproducible order in the archive.
    all_files = sorted(all_files.items())

    strip_prefixes = [p for p in arguments.strip_path_prefix]

    with WheelMaker(name=arguments.name,
                    version=arguments.version,
                    build_tag=arguments.build_tag,
                    python_tag=arguments.python_tag,
                    abi=arguments.abi,
                    platform=arguments.platform,
                    outfile=arguments.out,
                    strip_path_prefixes=strip_prefixes
                    ) as maker:
        for package_filename, real_filename in all_files:
            maker.add_file(package_filename, real_filename)
        maker.add_wheelfile()

        description = None
        if arguments.description_file:
            if sys.version_info[0] == 2:
                with open(arguments.description_file,
                          'rt') as description_file:
                    description = description_file.read()
            else:
                with open(arguments.description_file, 'rt',
                          encoding='utf-8') as description_file:
                    description = description_file.read()

        extra_requires = collections.defaultdict(list)
        if arguments.extra_requires:
            for extra in arguments.extra_requires:
                req, option = extra.rsplit(';', 1)
                extra_requires[option].append(req)
        classifiers = arguments.classifier or []
        python_requires = arguments.python_requires or ""
        requires = arguments.requires or []
        extra_headers = arguments.header or []

        maker.add_metadata(extra_headers=extra_headers,
                           description=description,
                           classifiers=classifiers,
                           python_requires=python_requires,
                           requires=requires,
                           extra_requires=extra_requires)

        if arguments.entry_points_file:
            maker.add_file(maker.distinfo_path(
                "entry_points.txt"), arguments.entry_points_file)

        maker.add_recordfile()


if __name__ == '__main__':
    main()
