# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Strip arm64e architecture from a binary if present."""

import argparse
import os
import shutil
import subprocess
import sys


def check_output(command):
    """Returns the output from |command| or propagates error, quitting script."""
    process = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    outs, errs = process.communicate()
    if process.returncode:
        sys.stderr.write(
            'error: command failed with retcode %d: %s\n\n'
            % (process.returncode, ' '.join(map(repr, command)))
        )
        sys.stderr.write(errs.decode('UTF-8', errors='ignore'))
        sys.exit(process.returncode)
    return outs.decode('UTF-8')


def check_call(command):
    """Invokes |command| or propagates error."""
    check_output(command)


def parse_args(args):
    """Parses the command-line."""
    parser = argparse.ArgumentParser()
    parser.add_argument('--input', required=True, help='Path to input binary')
    parser.add_argument('--output', required=True, help='Path to output binary')
    parser.add_argument(
        '--xcode-version', required=True, help='Version of Xcode'
    )
    return parser.parse_args(args)


def get_archs(path):
    """Extracts the architectures present in binary at |path|."""
    outputs = check_output(["xcrun", "lipo", "-info", os.path.abspath(path)])
    return outputs.split(': ')[-1].split()


def main(args):
    parsed = parse_args(args)

    outdir = os.path.dirname(parsed.output)
    if not os.path.isdir(outdir):
        os.makedirs(outdir)

    if os.path.exists(parsed.output):
        os.unlink(parsed.output)

    # As "lipo" fails with an error if asked to remove an architecture that is
    # not included, only use it if "arm64e" is present in the binary. Otherwise
    # simply copy the file.
    if 'arm64e' in get_archs(parsed.input):
        check_output(
            [
                "xcrun",
                "lipo",
                "-remove",
                "arm64e",
                "-output",
                os.path.abspath(parsed.output),
                os.path.abspath(parsed.input),
            ]
        )
    else:
        shutil.copy(parsed.input, parsed.output)


if __name__ == '__main__':
    main(sys.argv[1:])
