#!/usr/bin/env python3.8
# 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 errno
import json
import os
import shutil
import subprocess
import sys

from gen_library_metadata import get_sources

FUCHSIA_MODULE = 'go.fuchsia.dev/fuchsia'


def main():
    parser = argparse.ArgumentParser()
    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(
        '--ar', help='The archive linker to use', required=False, default='ar')
    parser.add_argument(
        '--dump-syms', help='The dump_syms tool to use', required=False)
    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(
        '--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('--buildidtool', help='The path to the buildidtool.')
    parser.add_argument(
        '--build-id-dir', help='The path to the .build-id directory.')
    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(
        '--golibs-dir',
        help='The directory containing third party libraries.',
        required=True)
    parser.add_argument(
        '--is-test', help='True if the target is a go test', default=False)
    parser.add_argument('--buildmode', help='Build mode to use')
    parser.add_argument(
        '--gcflag',
        help='Arguments to pass to Go compiler',
        action='append',
        default=[])
    parser.add_argument(
        '--ldflag',
        help='Arguments to pass to Go linker',
        action='append',
        default=[])
    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(
        '--output-path',
        help='Where to output the (unstripped) binary',
        required=True)
    parser.add_argument(
        '--stripped-output-path',
        help='Where to output a stripped binary, if supplied')
    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')
    parser.add_argument(
        '--tag', help='Add a go build tag', default=[], action='append')
    parser.add_argument(
        '--cgo', help='Whether to enable CGo', 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]

    dist = args.stripped_output_path or args.output_path

    # 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.
    gopath_src = os.path.join(project_path, 'src')
    # Manually removing all subdirectories and files instead of using
    # shutil.rmtree, to avoid registering spurious reads on stale
    # subdirectories. See https://fxbug.dev/74084.
    if os.path.exists(gopath_src):
        for root, dirs, files in os.walk(gopath_src, topdown=False):
            for file in files:
                os.unlink(os.path.join(root, file))
            for dir in dirs:
                full_path = os.path.join(root, dir)
                if os.path.islink(full_path):
                    os.unlink(full_path)
                else:
                    os.rmdir(full_path)

    dst_vendor = os.path.join(gopath_src, 'vendor')
    os.makedirs(dst_vendor)
    # Symlink interprets path against the current working directory, so use
    # absolute path for consistency.
    abs_golibs_dir = os.path.abspath(args.golibs_dir)
    for src in ['go.mod', 'go.sum']:
        os.symlink(
            os.path.join(abs_golibs_dir, src), os.path.join(gopath_src, src))
    os.symlink(
        os.path.join(os.path.join(abs_golibs_dir, 'vendor'), 'modules.txt'),
        os.path.join(dst_vendor, 'modules.txt'))

    if args.go_dep_files:
        # Create a GOPATH for the packages dependency tree.
        for dst, src in sorted(get_sources(args.go_dep_files).items()):
            # This path is later used in go commands that run in cwd=gopath_src.
            src = os.path.abspath(src)

            # If the destination is part of the "main module", strip off the
            # module path. Otherwise, put it in the vendor directory.
            if dst.startswith(FUCHSIA_MODULE):
                dst = os.path.relpath(dst, FUCHSIA_MODULE)
            else:
                dst = os.path.join('vendor', dst)

            if dst.endswith('/...'):
                # When a directory and all its subdirectories must be made available, map
                # the directory directly.
                dst = dst[:-4]
            elif os.path.isfile(src):
                # When sources are explicitly listed in the BUILD.gn file, each `src` will
                # be a path to a file that must be mapped directly.
                #
                # Paths with /.../ in the middle designate go packages that include
                # subpackages, but also explicitly list all their source files.
                #
                # The construction of these paths is done in the go list invocation, so we
                # remove these sentinel values here.
                dst = dst.replace('/.../', '/')
            else:
                raise ValueError(f'Invalid go_dep entry: {dst=}, {src=}')

            dstdir = os.path.join(gopath_src, dst)

            # Make a symlink to the src directory or file.
            parent = os.path.dirname(dstdir)
            if not os.path.exists(parent):
                os.makedirs(parent)
            # hardlink regular files instead of symlinking to handle non-Go
            # files that we want to embed using //go:embed, which doesn't
            # support symlinks.
            # TODO(https://fxbug.dev/81748): Add a separate mechanism for
            # declaring embedded files, and only hardlink those files
            # instead of hardlinking all sources.
            if os.path.isdir(src):
                os.symlink(src, dstdir)
            else:
                try:
                    os.link(src, dstdir)
                except OSError:
                    # Hardlinking may fail, for example if `src` is in a
                    # separate filesystem on a mounted device.
                    shutil.copyfile(src, dstdir)

    cflags = []
    if args.sysroot:
        cflags.extend(['--sysroot', os.path.abspath(args.sysroot)])
    if args.target:
        cflags.extend(['-target', args.target])

    ldflags = cflags[:]
    if args.current_os == 'linux':
        ldflags.extend(
            [
                '-stdlib=libc++',
                # TODO(fxbug.dev/64336): the following flags are not recognized by CGo.
                # '-rtlib=compiler-rt',
                # '-unwindlib=libunwind',
            ])

    for dir in args.include_dir:
        cflags.extend(['-isystem', os.path.abspath(dir)])
    ldflags.extend(['-L' + os.path.abspath(dir) for dir in args.lib_dir])

    cflags_joined = ' '.join(cflags)
    ldflags_joined = ' '.join(ldflags)

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

    env = {
        # /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.
        'PATH': os.path.join(build_goroot, 'bin') + ':/usr/bin:/bin',
        'GOARCH': goarch,
        'GOOS': goos,
        # GOPATH won't be used, but Go still insists that we set it. Without it,
        # Go emits the succinct error: `missing $GOPATH`. Go further insists
        # that $GOPATH/go.mod not exist; if we pass `gopath_src` here (which
        # is where we symlinked our go.mod), we get another succinct error:
        # `$GOPATH/go.mod exists but should not`. Finally, GOPATH must be
        # absolute, otherwise:
        #
        # go: GOPATH entry is relative; must be absolute path: ...
        # For more details see: 'go help gopath'
        #
        # and here we are.
        'GOPATH': os.path.abspath(project_path),
        # Disallow downloading modules from any source.
        #
        # See https://golang.org/ref/mod#environment-variables under `GOPROXY`.
        'GOPROXY': 'off',
        # Some users have GOROOT set in their parent environment, which can break
        # things, so it is always set explicitly here.
        'GOROOT': build_goroot,
        # GOCACHE, CC and CXX below may be used in different working directories
        # so they have to be absolute.
        'GOCACHE': os.path.abspath(args.go_cache),
        'AR': os.path.abspath(args.ar),
        'CC': os.path.abspath(args.cc),
        'CXX': os.path.abspath(args.cxx),
        'CGO_CFLAGS': cflags_joined,
        'CGO_CPPFLAGS': cflags_joined,
        'CGO_CXXFLAGS': cflags_joined,
        'CGO_LDFLAGS': ldflags_joined,
    }

    # Infra sets $TMPDIR which is cleaned between builds.
    if os.getenv('TMPDIR'):
        env['TMPDIR'] = os.getenv('TMPDIR')

    if args.cgo:
        env['CGO_ENABLED'] = '1'
    if args.target:
        env['CC_FOR_TARGET'] = env['CC']
        env['CXX_FOR_TARGET'] = env['CXX']

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

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

    cmd = [go_tool]
    if args.is_test:
        cmd += ['test', '-c']
    else:
        cmd += ['build', '-trimpath']
    if args.verbose:
        cmd += ['-x']
    if args.tag:
        # Separate tags by spaces. This behavior is actually deprecated in the
        # go command line, but Fuchsia currently has an older version of go
        # that hasn't switched to commas.
        cmd += ['-tags', ' '.join(args.tag)]
    if args.buildmode:
        cmd += ['-buildmode', args.buildmode]
        if args.buildmode == 'c-archive':
            if not args.ar:
                parser.error('--ar=AR is required with --buildmode=c-archive')
            args.ldflag.extend(['-extar', os.path.relpath(args.ar, gopath_src)])
    if args.gcflag:
        cmd += ['-gcflags', ' '.join(args.gcflag)]
    if args.ldflag:
        cmd += ['-ldflags=' + ' '.join(args.ldflag)]
    cmd += [
        '-pkgdir',
        os.path.join(project_path, 'pkg'),
        '-o',
        os.path.relpath(args.output_path, gopath_src),
        args.package,
    ]
    retcode = subprocess.call(cmd, env=env, cwd=gopath_src)
    if retcode != 0:
        return retcode

    if args.stripped_output_path:
        if args.current_os == 'mac':
            retcode = subprocess.call(
                [
                    'xcrun', 'strip', '-x', args.output_path, '-o',
                    args.stripped_output_path
                ],
                env=env)
        else:
            retcode = subprocess.call(
                [
                    args.objcopy, '--strip-sections', args.output_path,
                    args.stripped_output_path
                ],
                env=env)
        if retcode != 0:
            return retcode

    # TODO(fxbug.dev/27215): Also invoke the buildidtool in the case of linux
    # once buildidtool knows how to deal in Go's native build ID format.
    supports_build_id = args.current_os == 'fuchsia'
    if args.dump_syms and supports_build_id:
        if args.current_os == 'fuchsia':
            with open(dist + '.sym', 'w') as f:
                retcode = subprocess.call(
                    [args.dump_syms, '-r', '-o', 'Fuchsia', args.output_path],
                    stdout=f)
                if retcode != 0:
                    return retcode

    if args.buildidtool and supports_build_id:
        if not args.build_id_dir:
            raise ValueError('Using --buildidtool requires --build-id-dir')
        retcode = subprocess.call(
            [
                args.buildidtool,
                '-build-id-dir',
                args.build_id_dir,
                '-stamp',
                dist + '.build-id.stamp',
                '-entry',
                '.debug=' + args.output_path,
                '-entry',
                '=' + dist,
            ])
        if retcode != 0:
            return retcode

    go_list_args = [go_tool, 'list', '-json', '-deps']
    if args.is_test:
        go_list_args += ['-test']
    go_list_args += [args.package]
    output = subprocess.check_output(
        go_list_args, env=env, cwd=gopath_src, text=True)

    return 0


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