# Copyright 2016 Google Inc. 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.

"""Command line interface to subpar compiler"""

import argparse
import io
import os
import re

from subpar.compiler import error
from subpar.compiler import python_archive


def make_command_line_parser():
    """Return an object that can parse this program's command line"""
    parser = argparse.ArgumentParser(
        description='Subpar Python Executable Builder')

    parser.add_argument(
        'main_filename',
        help='Python source file to use as main entry point')

    parser.add_argument(
        '--manifest_file',
        help='File listing all files to be included in this parfile. This is ' +
        'typically generated by bazel in a target\'s .runfiles_manifest file.',
        required=True)
    parser.add_argument(
        '--manifest_root',
        help='Root directory of all relative paths in manifest file.',
        default=os.getcwd())
    parser.add_argument(
        '--outputpar',
        help='Filename of generated par file.',
        required=True)
    parser.add_argument(
        '--stub_file',
        help='Read imports and interpreter path from the specified stub file',
        required=True)
    return parser


def parse_stub(stub_filename):
    """Parse the imports and interpreter path from a py_binary() stub.

    We assume the stub is utf-8 encoded.

    TODO(b/29227737): Remove this once we can access imports from skylark.

    Returns (list of relative paths, path to Python interpreter)
    """

    # Find the list of import roots
    imports_regex = re.compile(r'''^  python_imports = '([^']*)'$''')
    interpreter_regex = re.compile(r'''^PYTHON_BINARY = '([^']*)'$''')
    import_roots = None
    interpreter = None
    with io.open(stub_filename, 'rt', encoding='utf8') as stub_file:
        for line in stub_file:
            importers_match = imports_regex.match(line)
            if importers_match:
                import_roots = importers_match.group(1).split(':')
                # Filter out empty paths
                import_roots = [x for x in import_roots if x]
            interpreter_match = interpreter_regex.match(line)
            if interpreter_match:
                interpreter = interpreter_match.group(1)
    if import_roots is None or not interpreter:
        raise error.Error('Failed to parse stub file [%s]' % stub_filename)

    # Find the Python interpreter, matching the search logic in
    # stub_template.txt
    if interpreter.startswith('//'):
        raise error.Error('Python interpreter must not be a label [%s]' %
                          stub_filename)
    elif interpreter.startswith('/'):
        pass
    elif '/' in interpreter:
        pass
    else:
        interpreter = '/usr/bin/env %s' % interpreter

    return (import_roots, interpreter)


def main(argv):
    """Command line interface to Subpar"""
    parser = make_command_line_parser()
    args = parser.parse_args(argv[1:])

    # Parse information from stub file that's too hard to compute in Skylark
    import_roots, interpreter = parse_stub(args.stub_file)

    par = python_archive.PythonArchive(
        main_filename=args.main_filename,
        import_roots=import_roots,
        interpreter=interpreter,
        output_filename=args.outputpar,
        manifest_filename=args.manifest_file,
        manifest_root=args.manifest_root,
    )
    par.create()
