#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2021 The ChromiumOS 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)
