#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Script to make / directory on chromebook writable.

This script updates a remote chromebook to make the / directory writable."
"""

from __future__ import print_function

__author__ = 'cmtice@google.com (Caroline Tice)'

import argparse
import os
import sys
import time

from cros_utils import command_executer
from cros_utils import locks
from cros_utils import logger
from cros_utils import machines
from cros_utils import misc

lock_file = '/tmp/image_chromeos_lock/image_chromeos_lock'


def Usage(parser, message):
  print('ERROR: %s' % message)
  parser.print_help()
  sys.exit(0)


def RebootChromebook(chromeos_root, remote, cmd_executer):
  cmd = 'sudo reboot'
  cmd_executer.CrosRunCommand(cmd, chromeos_root=chromeos_root, machine=remote)
  time.sleep(10)
  success = False
  for _ in range(1, 10):
    if machines.MachineIsPingable(remote):
      success = True
      break
    time.sleep(1)
  return success


def ParseOutput(output):
  # See comment in FindPartitionNum.
  lines = output.split('\n')
  num_str = '-1'
  for line in lines:
    l = line.strip()
    words = l.split()
    if (len(words) > 2 and words[0] == 'sudo' and
        words[1] == '/usr/share/vboot/bin/make_dev_ssd.sh' and
        words[-2] == '--partitions'):
      num_str = words[-1]
      break
  num = int(num_str)

  return num


def FindPartitionNum(chromeos_root, remote, logs, cmd_executer):
  partition_cmd = ('/usr/share/vboot/bin/make_dev_ssd.sh '
                   '--remove_rootfs_verification')
  _, output, _ = cmd_executer.CrosRunCommandWOutput(
      partition_cmd,
      chromeos_root=chromeos_root,
      machine=remote,
      terminated_timeout=10)

  # The command above, with no --partitions flag, should return output
  # in the following form:

  # make_dev_ssd.sh: INFO: checking system firmware...
  #
  #  ERROR: YOU ARE TRYING TO MODIFY THE LIVE SYSTEM IMAGE /dev/mmcblk0.
  #
  #  The system may become unusable after that change, especially when you have
  #  some auto updates in progress. To make it safer, we suggest you to only
  #  change the partition you have booted with. To do that, re-execute this
  #  command as:
  #
  #  sudo /usr/share/vboot/bin/make_dev_ssd.sh  --partitions 4
  #
  #  If you are sure to modify other partition, please invoke the command again
  #  and explicitly assign only one target partition for each time
  # (--partitions N )
  #
  # make_dev_ssd.sh: ERROR: IMAGE /dev/mmcblk0 IS NOT MODIFIED.

  # We pass this output to the ParseOutput function where it finds the 'sudo'
  # line with the partition number and returns the partition number.

  num = ParseOutput(output)

  if num == -1:
    logs.LogOutput('Failed to find partition number in "%s"' % output)
  return num


def TryRemoveRootfsFromPartition(chromeos_root, remote, cmd_executer,
                                 partition_num):
  partition_cmd = ('/usr/share/vboot/bin/make_dev_ssd.sh '
                   '--remove_rootfs_verification --partition %d' %
                   partition_num)
  ret = cmd_executer.CrosRunCommand(
      partition_cmd,
      chromeos_root=chromeos_root,
      machine=remote,
      terminated_timeout=10)
  return ret


def TryRemountPartitionAsRW(chromeos_root, remote, cmd_executer):
  command = 'sudo mount -o remount,rw /'
  ret = cmd_executer.CrosRunCommand(
      command,
      chromeos_root=chromeos_root,
      machine=remote,
      terminated_timeout=10)
  return ret


def Main(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '-c',
      '--chromeos_root',
      dest='chromeos_root',
      help='Target directory for ChromeOS installation.')
  parser.add_argument('-r', '--remote', dest='remote', help='Target device.')
  parser.add_argument(
      '-n',
      '--no_lock',
      dest='no_lock',
      default=False,
      action='store_true',
      help='Do not attempt to lock remote before imaging.  '
      'This option should only be used in cases where the '
      'exclusive lock has already been acquired (e.g. in '
      'a script that calls this one).')

  options = parser.parse_args(argv[1:])

  # Common initializations
  log_level = 'average'
  cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
  l = logger.GetLogger()

  if options.chromeos_root is None:
    Usage(parser, '--chromeos_root must be set')

  if options.remote is None:
    Usage(parser, '--remote must be set')

  options.chromeos_root = os.path.expanduser(options.chromeos_root)

  try:
    should_unlock = False
    if not options.no_lock:
      try:
        _ = locks.AcquireLock(
            list(options.remote.split()), options.chromeos_root)
        should_unlock = True
      except Exception as e:
        raise RuntimeError('Error acquiring machine: %s' % str(e))

    # Workaround for crosbug.com/35684.
    os.chmod(misc.GetChromeOSKeyFile(options.chromeos_root), 0o600)

    if log_level == 'average':
      cmd_executer.SetLogLevel('verbose')

    if not machines.MachineIsPingable(options.remote):
      raise RuntimeError('Machine %s does not appear to be up.' %
                         options.remote)

    ret = TryRemountPartitionAsRW(options.chromeos_root, options.remote,
                                  cmd_executer)

    if ret != 0:
      l.LogOutput('Initial mount command failed. Looking for root partition'
                  ' number.')
      part_num = FindPartitionNum(options.chromeos_root, options.remote, l,
                                  cmd_executer)
      if part_num != -1:
        l.LogOutput('Attempting to remove rootfs verification on partition %d' %
                    part_num)
        ret = TryRemoveRootfsFromPartition(options.chromeos_root,
                                           options.remote, cmd_executer,
                                           part_num)
        if ret == 0:
          l.LogOutput('Succeeded in removing roofs verification from'
                      ' partition %d. Rebooting...' % part_num)
          if not RebootChromebook(options.chromeos_root, options.remote,
                                  cmd_executer):
            raise RuntimeError('Chromebook failed to reboot.')
          l.LogOutput('Reboot succeeded. Attempting to remount partition.')
          ret = TryRemountPartitionAsRW(options.chromeos_root, options.remote,
                                        cmd_executer)
          if ret == 0:
            l.LogOutput('Re-mounted / as writable.')
          else:
            l.LogOutput('Re-mount failed. / is not writable.')
        else:
          l.LogOutput('Failed to remove rootfs verification from partition'
                      ' %d.' % part_num)
    else:
      l.LogOutput('Re-mounted / as writable.')

    l.LogOutput('Exiting.')

  finally:
    if should_unlock:
      locks.ReleaseLock(list(options.remote.split()), options.chromeos_root)

  return ret


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