#!/usr/bin/python2
#
# Copyright 2010 Google Inc. All Rights Reserved.
"""Script to enter the ChromeOS chroot with mounted sources.

This script enters the chroot with mounted sources.
"""

from __future__ import print_function

__author__ = 'asharif@google.com (Ahmad Sharif)'

import argparse
import getpass
import os
import pwd
import sys

from cros_utils import command_executer
from cros_utils import logger
from cros_utils import misc


class MountPoint(object):
  """Mount point class"""

  def __init__(self, external_dir, mount_dir, owner, options=None):
    self.external_dir = os.path.realpath(external_dir)
    self.mount_dir = os.path.realpath(mount_dir)
    self.owner = owner
    self.options = options

  def CreateAndOwnDir(self, dir_name):
    retv = 0
    if not os.path.exists(dir_name):
      command = 'mkdir -p ' + dir_name
      command += ' || sudo mkdir -p ' + dir_name
      retv = command_executer.GetCommandExecuter().RunCommand(command)
    if retv != 0:
      return retv
    pw = pwd.getpwnam(self.owner)
    if os.stat(dir_name).st_uid != pw.pw_uid:
      command = 'sudo chown -f ' + self.owner + ' ' + dir_name
      retv = command_executer.GetCommandExecuter().RunCommand(command)
    return retv

  def DoMount(self):
    ce = command_executer.GetCommandExecuter()
    mount_signature = '%s on %s' % (self.external_dir, self.mount_dir)
    command = 'mount'
    retv, out, _ = ce.RunCommandWOutput(command)
    if mount_signature not in out:
      retv = self.CreateAndOwnDir(self.mount_dir)
      logger.GetLogger().LogFatalIf(retv, 'Cannot create mount_dir!')
      retv = self.CreateAndOwnDir(self.external_dir)
      logger.GetLogger().LogFatalIf(retv, 'Cannot create external_dir!')
      retv = self.MountDir()
      logger.GetLogger().LogFatalIf(retv, 'Cannot mount!')
      return retv
    else:
      return 0

  def UnMount(self):
    ce = command_executer.GetCommandExecuter()
    return ce.RunCommand('sudo umount %s' % self.mount_dir)

  def MountDir(self):
    command = 'sudo mount --bind ' + self.external_dir + ' ' + self.mount_dir
    if self.options == 'ro':
      command += ' && sudo mount --bind -oremount,ro ' + self.mount_dir
    retv = command_executer.GetCommandExecuter().RunCommand(command)
    return retv

  def __str__(self):
    ret = ''
    ret += self.external_dir + '\n'
    ret += self.mount_dir + '\n'
    if self.owner:
      ret += self.owner + '\n'
    if self.options:
      ret += self.options + '\n'
    return ret


def Main(argv, return_output=False):
  """The main function."""

  parser = argparse.ArgumentParser()
  parser.add_argument('-c',
                      '--chromeos_root',
                      dest='chromeos_root',
                      default='../..',
                      help='ChromeOS root checkout directory.')
  parser.add_argument('-t',
                      '--toolchain_root',
                      dest='toolchain_root',
                      help='Toolchain root directory.')
  parser.add_argument('-o',
                      '--output',
                      dest='output',
                      help='Toolchain output directory')
  parser.add_argument('--sudo',
                      dest='sudo',
                      action='store_true',
                      default=False,
                      help='Run the command with sudo.')
  parser.add_argument('-r',
                      '--third_party',
                      dest='third_party',
                      help='The third_party directory to mount.')
  parser.add_argument('-m',
                      '--other_mounts',
                      dest='other_mounts',
                      help='Other mount points in the form: '
                      'dir:mounted_dir:options')
  parser.add_argument('-s',
                      '--mount-scripts-only',
                      dest='mount_scripts_only',
                      action='store_true',
                      default=False,
                      help='Mount only the scripts dir, and not the sources.')
  parser.add_argument('passthrough_argv', nargs='*',
                      help='Command to be executed inside the chroot.')

  options = parser.parse_args(argv)

  chromeos_root = options.chromeos_root

  chromeos_root = os.path.expanduser(chromeos_root)
  if options.toolchain_root:
    options.toolchain_root = os.path.expanduser(options.toolchain_root)

  chromeos_root = os.path.abspath(chromeos_root)

  tc_dirs = []
  if options.toolchain_root is None or options.mount_scripts_only:
    m = 'toolchain_root not specified. Will not mount toolchain dirs.'
    logger.GetLogger().LogWarning(m)
  else:
    tc_dirs = [options.toolchain_root + '/google_vendor_src_branch/gcc',
               options.toolchain_root + '/google_vendor_src_branch/binutils']

  for tc_dir in tc_dirs:
    if not os.path.exists(tc_dir):
      logger.GetLogger().LogError('toolchain path ' + tc_dir +
                                  ' does not exist!')
      parser.print_help()
      sys.exit(1)

  if not os.path.exists(chromeos_root):
    logger.GetLogger().LogError('chromeos_root ' + options.chromeos_root +
                                ' does not exist!')
    parser.print_help()
    sys.exit(1)

  if not os.path.exists(chromeos_root + '/src/scripts/build_packages'):
    logger.GetLogger(
    ).LogError(options.chromeos_root + '/src/scripts/build_packages'
               ' not found!')
    parser.print_help()
    sys.exit(1)

  version_dir = os.path.realpath(os.path.expanduser(os.path.dirname(__file__)))

  mounted_tc_root = '/usr/local/toolchain_root'
  full_mounted_tc_root = chromeos_root + '/chroot/' + mounted_tc_root
  full_mounted_tc_root = os.path.abspath(full_mounted_tc_root)

  mount_points = []
  for tc_dir in tc_dirs:
    last_dir = misc.GetRoot(tc_dir)[1]
    mount_point = MountPoint(tc_dir, full_mounted_tc_root + '/' + last_dir,
                             getpass.getuser(), 'ro')
    mount_points.append(mount_point)

  # Add the third_party mount point if it exists
  if options.third_party:
    third_party_dir = options.third_party
    logger.GetLogger().LogFatalIf(
        not os.path.isdir(third_party_dir),
        '--third_party option is not a valid dir.')
  else:
    third_party_dir = os.path.abspath('%s/../../../third_party' %
                                      os.path.dirname(__file__))

  if os.path.isdir(third_party_dir):
    mount_point = MountPoint(third_party_dir, ('%s/%s' % (
        full_mounted_tc_root, os.path.basename(third_party_dir))),
                             getpass.getuser())
    mount_points.append(mount_point)

  output = options.output
  if output is None and options.toolchain_root:
    # Mount the output directory at /usr/local/toolchain_root/output
    output = options.toolchain_root + '/output'

  if output:
    mount_points.append(MountPoint(output, full_mounted_tc_root + '/output',
                                   getpass.getuser()))

  # Mount the other mount points
  mount_points += CreateMountPointsFromString(options.other_mounts,
                                              chromeos_root + '/chroot/')

  last_dir = misc.GetRoot(version_dir)[1]

  # Mount the version dir (v14) at /usr/local/toolchain_root/v14
  mount_point = MountPoint(version_dir, full_mounted_tc_root + '/' + last_dir,
                           getpass.getuser())
  mount_points.append(mount_point)

  for mount_point in mount_points:
    retv = mount_point.DoMount()
    if retv != 0:
      return retv

  # Finally, create the symlink to build-gcc.
  command = 'sudo chown ' + getpass.getuser() + ' ' + full_mounted_tc_root
  retv = command_executer.GetCommandExecuter().RunCommand(command)

  try:
    CreateSymlink(last_dir + '/build-gcc', full_mounted_tc_root + '/build-gcc')
    CreateSymlink(last_dir + '/build-binutils',
                  full_mounted_tc_root + '/build-binutils')
  except Exception as e:
    logger.GetLogger().LogError(str(e))

  # Now call cros_sdk --enter with the rest of the arguments.
  command = 'cd %s/src/scripts && cros_sdk --enter' % chromeos_root

  if len(options.passthrough_argv) > 1:
    inner_command = ' '.join(options.passthrough_argv[1:])
    inner_command = inner_command.strip()
    if inner_command.startswith('-- '):
      inner_command = inner_command[3:]
    command_file = 'tc_enter_chroot.cmd'
    command_file_path = chromeos_root + '/src/scripts/' + command_file
    retv = command_executer.GetCommandExecuter().RunCommand('sudo rm -f ' +
                                                            command_file_path)
    if retv != 0:
      return retv
    f = open(command_file_path, 'w')
    f.write(inner_command)
    f.close()
    logger.GetLogger().LogCmd(inner_command)
    retv = command_executer.GetCommandExecuter().RunCommand('chmod +x ' +
                                                            command_file_path)
    if retv != 0:
      return retv

    if options.sudo:
      command += ' sudo ./' + command_file
    else:
      command += ' ./' + command_file
    retv = command_executer.GetCommandExecuter().RunCommandGeneric(
        command, return_output)
    return retv
  else:
    os.chdir('%s/src/scripts' % chromeos_root)
    ce = command_executer.GetCommandExecuter()
    _, out, _ = ce.RunCommandWOutput('which cros_sdk')
    cros_sdk_binary = out.split()[0]
    return os.execv(cros_sdk_binary, ['', '--enter'])


def CreateMountPointsFromString(mount_strings, chroot_dir):
  # String has options in the form dir:mount:options
  mount_points = []
  if not mount_strings:
    return mount_points
  mount_list = mount_strings.split()
  for mount_string in mount_list:
    mount_values = mount_string.split(':')
    external_dir = mount_values[0]
    mount_dir = mount_values[1]
    if len(mount_values) > 2:
      options = mount_values[2]
    else:
      options = None
    mount_point = MountPoint(external_dir, chroot_dir + '/' + mount_dir,
                             getpass.getuser(), options)
    mount_points.append(mount_point)
  return mount_points


def CreateSymlink(target, link_name):
  logger.GetLogger().LogFatalIf(
      target.startswith('/'), "Can't create symlink to absolute path!")
  real_from_file = misc.GetRoot(link_name)[0] + '/' + target
  if os.path.realpath(real_from_file) != os.path.realpath(link_name):
    if os.path.exists(link_name):
      command = 'rm -rf ' + link_name
      command_executer.GetCommandExecuter().RunCommand(command)
    os.symlink(target, link_name)


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