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

import argparse
import os
import subprocess
import sys

# When passed the --setup flag, this script fetches git submodules and other
# dependencies for the impeller-cmake-example. When passed the --cmake flag,
# this script runs cmake on impeller-cmake-example. That will create
# a build output directory for impeller-cmake-example under
# out/impeller-cmake-example, so the build can then be performed with
# e.g. ninja -C out/impeller-cmake-example-out.

SRC_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def parse_args(argv):
  parser = argparse.ArgumentParser(
      description='A script that tests the impeller-cmake-example build.',
  )
  parser.add_argument(
      '--cmake',
      '-c',
      default=False,
      action='store_true',
      help='Run cmake for impeller-cmake-example.',
  )
  parser.add_argument(
      '--goma-dir',
      '-g',
      type=str,
      default=os.getenv('GOMA_DIR'),
      help=(
          'The path to the Goma install. Defaults to the value of the '
          'GOMA_DIR environment variable.'
      ),
  )
  parser.add_argument(
      '--path',
      '-p',
      type=str,
      help='The path to the impeller-cmake-example source.',
  )
  parser.add_argument(
      '--setup',
      '-s',
      default=False,
      action='store_true',
      help='Clone the git submodules.',
  )
  parser.add_argument(
      '--verbose',
      '-v',
      default=False,
      action='store_true',
      help='Emit verbose output.',
  )
  parser.add_argument(
      '--xcode-symlinks',
      default=False,
      action='store_true',
      help='Symlink the Xcode sysroot to help Goma be successful.',
  )
  return parser.parse_args(argv)


def validate_args(args):
  if not os.path.isdir(os.path.join(SRC_ROOT, args.path)):
    print(
        'The --path argument must be a valid directory relative to the '
        'engine src/ directory.'
    )
    return False

  return True


def create_xcode_symlink():
  find_sdk_command = [
      'python3',
      os.path.join(SRC_ROOT, 'build', 'mac', 'find_sdk.py'),
      '--print_sdk_path',
      '10.15',
      '--symlink',
      os.path.join(SRC_ROOT, 'out', 'impeller-cmake-example-xcode-sysroot'),
  ]
  find_sdk_output = subprocess.check_output(find_sdk_command).decode('utf-8')
  return find_sdk_output.split('\n')[0]


def main(argv):
  args = parse_args(argv[1:])
  if not validate_args(args):
    return 1

  impeller_cmake_dir = os.path.join(SRC_ROOT, args.path)

  if args.setup:
    git_command = [
        'git',
        '-C',
        impeller_cmake_dir,
        'submodule',
        'update',
        '--init',
        '--recursive',
        '--depth',
        '1',
        '--jobs',
        str(os.cpu_count()),
    ]
    subprocess.check_call(git_command)

    # Run the deps.sh shell script in the repo.
    subprocess.check_call(['bash', 'deps.sh'], cwd=impeller_cmake_dir)
    return 0

  if args.cmake:
    cmake_path = os.path.join(SRC_ROOT, 'buildtools', 'mac-x64', 'cmake', 'bin', 'cmake')
    cmake_command = [
        cmake_path,
        '--preset',
        'flutter-ci-mac-debug-x64',
        '-B',
        os.path.join(SRC_ROOT, 'out', 'impeller-cmake-example'),
    ]
    cmake_env = os.environ.copy()
    ninja_path = os.path.join(SRC_ROOT, 'flutter', 'third_party', 'ninja')
    cmake_env.update({
        'PATH': os.environ['PATH'] + ':' + ninja_path,
        'FLUTTER_ENGINE_SRC_DIR': SRC_ROOT,
        'FLUTTER_GOMA_DIR': args.goma_dir,
    })
    if args.xcode_symlinks:
      xcode_symlink_path = create_xcode_symlink()
      cmake_env.update({
          'FLUTTER_OSX_SYSROOT': xcode_symlink_path,
      })
    subprocess.check_call(cmake_command, env=cmake_env, cwd=impeller_cmake_dir)

  return 0


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