#!/usr/bin/env python
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Build script for a Go app.

import argparse
import os
import subprocess
import sys
import string
import shutil
import errno

from gen_library_metadata import get_sources


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--godepfile', help='Path to godepfile tool', required=True)
    parser.add_argument('--root-out-dir', help='Path to root of build output',
                        required=True)
    parser.add_argument('--cc', help='The C compiler to use',
                        required=False, default='cc')
    parser.add_argument('--cxx', help='The C++ compiler to use',
                        required=False, default='c++')
    parser.add_argument('--objcopy', help='The objcopy tool to use',
                        required=False, default='objcopy')
    parser.add_argument('--sysroot', help='The sysroot to use',
                        required=False)
    parser.add_argument('--target', help='The compiler target to use',
                        required=False)
    parser.add_argument('--depfile', help='The path to the depfile',
                        required=True)
    parser.add_argument('--current-cpu', help='Target architecture.',
                        choices=['x64', 'arm64'], required=True)
    parser.add_argument('--current-os', help='Target operating system.',
                        choices=['fuchsia', 'linux', 'mac', 'win'], required=True)
    parser.add_argument('--go-root', help='The go root to use for builds.', required=True)
    parser.add_argument('--go-cache', help='Cache directory to use for builds.',
                        required=False)
    parser.add_argument('--is-test', help='True if the target is a go test',
                        default=False)
    parser.add_argument('--go-dep-files',
                        help='List of files describing library dependencies',
                        nargs='*',
                        default=[])
    parser.add_argument('--binname', help='Output file', required=True)
    parser.add_argument('--unstripped-binname', help='Unstripped output file')
    parser.add_argument('--verbose', help='Tell the go tool to be verbose about what it is doing',
                        action='store_true')
    parser.add_argument('--package', help='The package name', required=True)
    parser.add_argument('--include-dir', help='-isystem path to add',
                        action='append', default=[])
    parser.add_argument('--lib-dir', help='-L path to add',
                        action='append', default=[])
    parser.add_argument('--vet', help='Run go vet',
                        action='store_true')
    args = parser.parse_args()

    try:
        os.makedirs(args.go_cache)
    except OSError as e:
        if e.errno == errno.EEXIST and os.path.isdir(args.go_cache):
            pass
        else:
            raise

    goarch = {
        'x64': 'amd64',
        'arm64': 'arm64',
    }[args.current_cpu]
    goos = {
        'fuchsia': 'fuchsia',
        'linux': 'linux',
        'mac': 'darwin',
        'win': 'windows',
    }[args.current_os]

    output_name = os.path.join(args.root_out_dir, args.binname)
    build_id_dir = os.path.join(args.root_out_dir, '.build-id')
    depfile_output = output_name
    if args.unstripped_binname:
        stripped_output_name = output_name
        output_name = os.path.join(args.root_out_dir, 'exe.unstripped',
                                   args.binname)

    # Project path is a package specific gopath, also known as a "project" in go parlance.
    project_path = os.path.join(args.root_out_dir, 'gen', 'gopaths', args.binname)

    # Clean up any old project path to avoid leaking old dependencies
    shutil.rmtree(os.path.join(project_path, 'src'), ignore_errors=True)
    os.makedirs(os.path.join(project_path, 'src'))

    if args.go_dep_files:
      # Create a gopath for the packages dependency tree
      for dst, src in get_sources(args.go_dep_files).items():
        dstdir = os.path.join(project_path, 'src', os.path.dirname(dst))
        try:
          os.makedirs(dstdir)
        except OSError as e:
          # EEXIST occurs if two gopath entries share the same parent name
          if e.errno != errno.EEXIST:
            raise
        # TODO(BLD-228): the following check might not be necessary anymore.
        tgt = os.path.join(dstdir, os.path.basename(dst))
        # The source tree is effectively read-only once the build begins.
        # Therefore it is an error if tgt is in the source tree. At first
        # glance this may seem impossible, but it can happen if dst is foo/bar
        # and foo is a symlink back to the source tree.
        canon_root_out_dir = os.path.realpath(args.root_out_dir)
        canon_tgt = os.path.realpath(tgt)
        if not canon_tgt.startswith(canon_root_out_dir):
          raise ValueError("Dependency destination not in --root-out-dir: provided=%s, path=%s, realpath=%s" % (dst, tgt, canon_tgt))
        os.symlink(os.path.relpath(src, os.path.dirname(tgt)), tgt)

    gopath = os.path.abspath(project_path)
    build_goroot = os.path.abspath(args.go_root)

    env = {}
    env['GOARCH'] = goarch
    env['GOOS'] = goos
    env['GOPATH'] = gopath
    # Some users have GOROOT set in their parent environment, which can break
    # things, so it is always set explicitly here.
    env['GOROOT'] = build_goroot
    env['GOCACHE'] = args.go_cache

    env['CC'] = args.cc
    if args.target:
        env['CC_FOR_TARGET'] = args.cc
    env['CXX'] = args.cxx
    if args.target:
        env['CXX_FOR_TARGET'] = args.cxx

    cflags = []
    if args.sysroot:
        cflags.append('--sysroot=' + args.sysroot)
    if args.target:
        cflags.append('--target=' + args.target)
    ldflags = cflags[:]

    cflags += ['-isystem' + dir for dir in args.include_dir]
    ldflags += ['-L' + dir for dir in args.lib_dir]

    env['CGO_CFLAGS'] = env['CGO_CPPFLAGS'] = env['CGO_CXXFLAGS'] = ' '.join(cflags)
    env['CGO_LDFLAGS'] = ' '.join(ldflags)
    env['CGO_ENABLED'] = '1'

    # /usr/bin:/bin are required for basic things like bash(1) and env(1). Note
    # that on Mac, ld is also found from /usr/bin.
    env['PATH'] = "/usr/bin:/bin"

    go_tool = os.path.join(build_goroot, 'bin/go')

    if args.vet:
        retcode = subprocess.call([go_tool, 'vet', args.package], env=env)
        if retcode != 0:
          return retcode

    cmd = [go_tool]
    if args.is_test:
      cmd += ['test', '-c']
    else:
      cmd += ['build']
    if args.verbose:
      cmd += ['-x']
    cmd += ['-pkgdir', os.path.join(project_path, 'pkg'), '-o',
            output_name, args.package]
    retcode = subprocess.call(cmd, env=env)

    if retcode == 0 and args.unstripped_binname:
        if args.current_os == 'mac':
            retcode = subprocess.call(['xcrun', 'strip', '-x', output_name,
                                       '-o', stripped_output_name],
                                      env=env)
        else:
            retcode = subprocess.call([args.objcopy,
                                       '--strip-sections',
                                       '--build-id-link-dir=%s' % build_id_dir,
                                       '--build-id-link-input=.debug',
                                       '--build-id-link-output=',
                                       output_name,
                                       stripped_output_name],
                                      env=env)

    if retcode == 0:
        if args.depfile is not None:
            with open(args.depfile, "wb") as out:
                godepfile_args = [args.godepfile, '-o', depfile_output]
                if args.is_test:
                    godepfile_args += [ '-test']
                godepfile_args += [args.package]
                subprocess.Popen(godepfile_args, stdout=out, env=env)

    return retcode


if __name__ == '__main__':
    sys.exit(main())
