#!/usr/bin/env python3
# Copyright (C) 2019 The Android Open Source Project
#
# 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.

from __future__ import print_function
import argparse
import distutils
import errno
import grp
import os
import readline
import sys
import shutil
import subprocess
from pipes import quote
from subprocess import check_call

try:
  from shutil import which as find_executable
except AttributeError:
  from distutils.spawn import find_executable

REPO_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.path.join(REPO_ROOT, 'infra', 'ci'))
from config import JOB_CONFIGS, SANDBOX_IMG

try:
  input = raw_input
except NameError:
  pass


def user_in_docker_group():
  try:
    group = grp.getgrnam('docker')
  except KeyError:
    return False
  else:
    return group.gr_gid in os.getgroups()


def decision(question='Would you like to continue', confirm=True, default='n'):
  default = default.lower().strip()
  yes = default in {'y', 'yes'}
  no = default in {'n', 'no'}
  default = 'y' if yes else 'n'
  prompt = '%s? [%s/%s]: ' % (question, 'Y' if yes else 'y', 'N' if no else 'n')
  if not confirm:
    print('%sy' % prompt)
    return
  while True:
    choice = input(prompt).lower().strip()
    if not choice:
      choice = default
    if choice in {'y', 'yes'}:
      return
    elif choice in {'n', 'no'}:
      sys.exit(3)


def main():
  parser = argparse.ArgumentParser(
      formatter_class=argparse.ArgumentDefaultsHelpFormatter)
  parser.add_argument('config', choices=JOB_CONFIGS.keys())
  parser.add_argument(
      '--runner',
      help='The container runner executable to use',
      choices=('podman', 'docker'),
      default='podman' if find_executable('podman') else 'docker')
  parser.add_argument(
      '--build',
      action='store_true',
      help='Will perform a build of sandbox image')
  group = parser.add_mutually_exclusive_group()
  group.add_argument(
      '--confirm',
      action='store_true',
      default=True,
      help='User confirmation of decision prompts')
  group.add_argument(
      '--no-confirm',
      dest='confirm',
      action='store_false',
      help='Forces confirmation of decision prompts')
  args = parser.parse_args()

  # Check that the directory is clean.
  git_cmd = ['git', '-C', REPO_ROOT, 'status', '--porcelain']
  modified_files = subprocess.check_output(git_cmd).decode()
  if modified_files:
    print('The current Git repo has modified/untracked files.')
    print('The sandboxed VM will fetch the HEAD of your current git repo.')
    print('This is probably not the state you want to be in.')
    print('I suggest you stop, commit and then re-run this script')
    print('Modified files:\n' + modified_files)
    decision('Do you know what you are doing', confirm=args.confirm)

  if args.build:
    print('')
    print('About to build %r locally with %r' % (args.image, args.runner))
    decision(confirm=args.confirm)
    check_call(('make', '-C', os.path.join(REPO_ROOT, 'infra',
                                           'ci'),
                'BUILDER=%s' % args.runner, 'build-sandbox'))

  bundle_path = '/tmp/perfetto-ci.bundle'
  check_call(['git', '-C', REPO_ROOT, 'bundle', 'create', bundle_path, 'HEAD' ])
  os.chmod(bundle_path, 0o664)
  env = {
      'PERFETTO_TEST_GIT_REF': bundle_path,
  }
  env.update(JOB_CONFIGS[args.config])

  workdir = os.path.join(REPO_ROOT, 'out', 'tmp.ci')
  cmd = []
  if args.runner == 'docker' and not user_in_docker_group():
    cmd += ['sudo', '--']
  cmd += [
      args.runner, 'run', '-it', '--name', 'perfetto_ci', '--cap-add',
      'SYS_PTRACE', '--rm', '--volume',
      '%s:/ci/ramdisk' % workdir, '--tmpfs', '/tmp:exec',
      '--volume=%s:%s:ro' % (bundle_path, bundle_path)
  ]
  for kv in env.items():
    cmd += ['--env', '%s=%s' % kv]
  cmd += [SANDBOX_IMG]
  cmd += [
      'bash', '-c',
      'cd /ci/ramdisk; bash /ci/init.sh || sudo -u perfetto -EH bash -i'
  ]

  print(
      'About to run\n',
      ' '.join('\n  ' + c if c.startswith('--') or c == 'bash' else quote(c)
               for c in cmd))
  print('')
  print('The VM workdir /ci/ramdisk will be mounted into: %s' % workdir)
  print('The contents of %s will be deleted before starting the VM' % workdir)
  decision(confirm=args.confirm)

  try:
    shutil.rmtree(workdir)
  except EnvironmentError as e:
    if e.errno == errno.ENOENT:
      pass
    elif e.errno == errno.EACCES:
      print('')
      print('Removing previous volume %r' % workdir)
      check_call(('sudo', 'rm', '-r', quote(workdir)))
    else:
      raise

  os.makedirs(workdir)
  os.execvp(cmd[0], cmd)


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