# Copyright 2019 Google LLC
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


import posixpath
from recipe_engine import recipe_api


MOUNT_SRC = '/SRC'
MOUNT_OUT = '/OUT'


class DockerApi(recipe_api.RecipeApi):
  def _chmod(self, filepath, mode, recursive=False):
    cmd = ['chmod']
    if recursive:
      cmd.append('-R')
    cmd.extend([mode, filepath])
    name = ' '.join([str(elem) for elem in cmd])
    self.m.step(name, cmd=cmd, infra_step=True)

  def mount_src(self):
    return MOUNT_SRC

  def mount_out(self):
    return MOUNT_OUT

  # Unless match_directory_structure ==True, src_dir must be
  # self.m.path['start_dir'] for the script to be located correctly.
  def run(self, name, docker_image, src_dir, out_dir, script, args=None, docker_args=None, copies=None, recursive_read=None, attempts=1, match_directory_structure=False):
    # Setup. Docker runs as a different user, so we need to give it access to
    # read, write, and execute certain files.
    with self.m.step.nest('Docker setup'):
      step_stdout = self.m.python.inline(
          name='Get uid and gid',
          program='''import os
print('%d:%d' % (os.getuid(), os.getgid()))
''',
          stdout=self.m.raw_io.output(),
          step_test_data=(
              lambda: self.m.raw_io.test_api.stream_output('13:17'))
          ).stdout.decode('utf-8')
      uid_gid_pair = step_stdout.rstrip() if step_stdout else ''
      # Make sure out_dir exists, otherwise mounting will fail.
      # (Note that the docker --mount option, unlike the --volume option, does
      # not create this dir as root if it doesn't exist.)
      self.m.file.ensure_directory('mkdirs out_dir', out_dir, mode=0o777)
      # ensure_directory won't change the permissions if the dir already exists,
      # so we need to do that explicitly.
      self._chmod(out_dir, '777')

      # chmod the src_dir, but not recursively; Swarming writes some files which
      # we can't access, so "chmod -R" will fail if this is the root workdir.
      self._chmod(src_dir, '755')

      # Need to make the script executable, or Docker can't run it.
      self._chmod(script, '0755')

      # Copy any requested files.
      if copies:
        for copy in copies:
          src = copy['src']
          dest = copy['dst']
          dirname = self.m.path.dirname(dest)
          self.m.file.ensure_directory(
              'mkdirs %s' % dirname, dirname, mode=0o777)
          self.m.file.copy('cp %s %s' % (src, dest), src, dest)
          self._chmod(dest, '644')

      # Recursive chmod any requested directories.
      if recursive_read:
        for elem in recursive_read:
          self._chmod(elem, 'a+r', recursive=True)

    # Run.
    cmd = [
      'docker', 'run', '--shm-size=2gb', '--rm', '--user', uid_gid_pair,
      '--mount', 'type=bind,source=%s,target=%s' %
                 (src_dir, src_dir if match_directory_structure else MOUNT_SRC),
      '--mount', 'type=bind,source=%s,target=%s' %
                 (out_dir, out_dir if match_directory_structure else MOUNT_OUT),
    ]
    if docker_args:
      cmd.extend(docker_args)
    if not match_directory_structure:
      # This only works when src_dir == self.m.path['start_dir'] but that's our
      # only use case for now.
      script = MOUNT_SRC + '/' + posixpath.relpath(str(script), str(self.m.path['start_dir']))
    cmd.extend([docker_image, script])
    if args:
      cmd.extend(args)

    env = {'DOCKER_CONFIG': '/home/chrome-bot/.docker'}
    with self.m.env(env):
      self.m.run.with_retry(self.m.step, name, attempts, cmd=cmd)
