#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 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.

"""A manager for patches."""

from __future__ import print_function

from collections import namedtuple
from failure_modes import FailureModes
from subprocess_helpers import check_call
from subprocess_helpers import check_output

import argparse
import json
import get_llvm_hash
import os
import subprocess
import sys


def is_directory(dir_path):
  """Validates that the argument passed into 'argparse' is a directory."""

  if not os.path.isdir(dir_path):
    raise ValueError('Path is not a directory: %s' % dir_path)

  return dir_path


def is_patch_metadata_file(patch_metadata_file):
  """Valides the argument into 'argparse' is a patch file."""

  if not os.path.isfile(patch_metadata_file):
    raise ValueError(
        'Invalid patch metadata file provided: %s' % patch_metadata_file)

  if not patch_metadata_file.endswith('.json'):
    raise ValueError(
        'Patch metadata file does not end in ".json": %s' % patch_metadata_file)

  return patch_metadata_file


def is_valid_failure_mode(failure_mode):
  """Validates that the failure mode passed in is correct."""

  cur_failure_modes = [mode.value for mode in FailureModes]

  if failure_mode not in cur_failure_modes:
    raise ValueError('Invalid failure mode provided: %s' % failure_mode)

  return failure_mode


def EnsureBisectModeAndSvnVersionAreSpecifiedTogether(failure_mode,
                                                      good_svn_version):
  """Validates that 'good_svn_version' is passed in only for bisection."""

  if failure_mode != FailureModes.BISECT_PATCHES.value and good_svn_version:
    raise ValueError('"good_svn_version" is only available for bisection.')
  elif failure_mode == FailureModes.BISECT_PATCHES.value and \
      not good_svn_version:
    raise ValueError('A good SVN version is required for bisection (used by'
                     '"git bisect start".')


def GetCommandLineArgs():
  """Get the required arguments from the command line."""

  # Create parser and add optional command-line arguments.
  parser = argparse.ArgumentParser(description='A manager for patches.')

  # Add argument for the last good SVN version which is required by
  # `git bisect start` (only valid for bisection mode).
  parser.add_argument(
      '--good_svn_version',
      type=int,
      help='INTERNAL USE ONLY... (used for bisection.)')

  # Add argument for the number of patches it iterate. Only used when performing
  # `git bisect run`.
  parser.add_argument(
      '--num_patches_to_iterate', type=int, help=argparse.SUPPRESS)

  # Add argument for whether bisection should continue. Only used for
  # 'bisect_patches.'
  parser.add_argument(
      '--continue_bisection',
      type=bool,
      default=False,
      help='Determines whether bisection should continue after successfully '
      'bisecting a patch (default: %(default)s) - only used for '
      '"bisect_patches"')

  # Add argument for the LLVM version to use for patch management.
  parser.add_argument(
      '--svn_version',
      type=int,
      required=True,
      help='the LLVM svn version to use for patch management (determines '
      'whether a patch is applicable)')

  # Add argument for the patch metadata file that is in $FILESDIR.
  parser.add_argument(
      '--patch_metadata_file',
      required=True,
      type=is_patch_metadata_file,
      help='the absolute path to the .json file in "$FILESDIR/" of the '
      'package which has all the patches and their metadata if applicable')

  # Add argument for the absolute path to the ebuild's $FILESDIR path.
  # Example: '.../sys-devel/llvm/files/'.
  parser.add_argument(
      '--filesdir_path',
      required=True,
      type=is_directory,
      help='the absolute path to the ebuild "files/" directory')

  # Add argument for the absolute path to the unpacked sources.
  parser.add_argument(
      '--src_path',
      required=True,
      type=is_directory,
      help='the absolute path to the unpacked LLVM sources')

  # Add argument for the mode of the patch manager when handling failing
  # applicable patches.
  parser.add_argument(
      '--failure_mode',
      default=FailureModes.FAIL.value,
      type=is_valid_failure_mode,
      help='the mode of the patch manager when handling failed patches ' \
          '(default: %(default)s)')

  # Parse the command line.
  args_output = parser.parse_args()

  EnsureBisectModeAndSvnVersionAreSpecifiedTogether(
      args_output.failure_mode, args_output.good_svn_version)

  return args_output


def GetHEADSVNVersion(src_path):
  """Gets the SVN version of HEAD in the src tree."""

  cmd = ['git', '-C', src_path, 'rev-parse', 'HEAD']

  git_hash = check_output(cmd)

  version = get_llvm_hash.GetVersionFrom(src_path, git_hash.rstrip())

  return version


def VerifyHEADIsTheSameAsSVNVersion(src_path, svn_version):
  """Verifies that HEAD's SVN version matches 'svn_version'."""

  head_svn_version = GetHEADSVNVersion(src_path)

  if head_svn_version != svn_version:
    raise ValueError('HEAD\'s SVN version %d does not match "svn_version"'
                     ' %d, please move HEAD to "svn_version"s\' git hash.' %
                     (head_svn_version, svn_version))


def GetPathToPatch(filesdir_path, rel_patch_path):
  """Gets the absolute path to a patch in $FILESDIR.

  Args:
    filesdir_path: The absolute path to $FILESDIR.
    rel_patch_path: The relative path to the patch in '$FILESDIR/'.

  Returns:
    The absolute path to the patch in $FILESDIR.

  Raises:
    ValueError: Unable to find the path to the patch in $FILESDIR.
  """

  if not os.path.isdir(filesdir_path):
    raise ValueError('Invalid path to $FILESDIR provided: %s' % filesdir_path)

  # Combine $FILESDIR + relative path of patch to $FILESDIR.
  patch_path = os.path.join(filesdir_path, rel_patch_path)

  if not os.path.isfile(patch_path):
    raise ValueError('The absolute path %s to the patch %s does not exist' %
                     (patch_path, rel_patch_path))

  return patch_path


def GetPatchMetadata(patch_dict):
  """Gets the patch's metadata.

  Args:
    patch_dict: A dictionary that has the patch metadata.

  Returns:
    A tuple that contains the metadata values.
  """

  # Get the metadata values of a patch if possible.
  start_version = patch_dict.get('start_version', 0)
  end_version = patch_dict.get('end_version', None)
  is_critical = patch_dict.get('is_critical', False)

  return start_version, end_version, is_critical


def ApplyPatch(src_path, patch_path):
  """Attempts to apply the patch.

  Args:
    src_path: The absolute path to the unpacked sources of the package.
    patch_path: The absolute path to the patch in $FILESDIR/

  Returns:
    A boolean where 'True' means that the patch applied fine or 'False' means
    that the patch failed to apply.
  """

  if not os.path.isdir(src_path):
    raise ValueError('Invalid src path provided: %s' % src_path)

  if not os.path.isfile(patch_path):
    raise ValueError('Invalid patch file provided: %s' % patch_path)

  # Test the patch with '--dry-run' before actually applying the patch.
  test_patch_cmd = [
      'patch', '--dry-run', '-d', src_path, '-f', '-p1', '-E',
      '--no-backup-if-mismatch', '-i', patch_path
  ]

  # Cmd to apply a patch in the src unpack path.
  apply_patch_cmd = [
      'patch', '-d', src_path, '-f', '-p1', '-E', '--no-backup-if-mismatch',
      '-i', patch_path
  ]

  try:
    check_output(test_patch_cmd)

  # If the mode is 'continue', then catching the exception makes sure that
  # the program does not exit on the first failed applicable patch.
  except subprocess.CalledProcessError:
    # Test run on the patch failed to apply.
    return False

  # Test run succeeded on the patch.
  check_output(apply_patch_cmd)

  return True


def UpdatePatchMetadataFile(patch_metadata_file, patches):
  """Updates the .json file with unchanged and at least one changed patch.

  Args:
    patch_metadata_file: The absolute path to the .json file that has all the
    patches and its metadata.
    patches: A list of patches whose metadata were or were not updated.

  Raises:
    ValueError: The patch metadata file does not have the correct extension.
  """

  if not patch_metadata_file.endswith('.json'):
    raise ValueError('File does not end in ".json": %s' % patch_metadata_file)

  with open(patch_metadata_file, 'w') as patch_file:
    json.dump(patches, patch_file, indent=4, separators=(',', ': '))


def GetCommitHashesForBisection(src_path, good_svn_version, bad_svn_version):
  """Gets the good and bad commit hashes required by `git bisect start`."""

  new_llvm_hash = LLVMHash()

  bad_commit_hash = get_llvm_hash.GetGitHashFrom(src_path, bad_svn_version)

  good_commit_hash = get_llvm_hash.GetGitHashFrom(src_path, good_svn_version)

  return good_commit_hash, bad_commit_hash


def PerformBisection(src_path, good_commit, bad_commit, svn_version,
                     patch_metadata_file, filesdir_path, num_patches):
  """Performs bisection to determine where a patch stops applying."""

  start_cmd = [
      'git', '-C', src_path, 'bisect', 'start', bad_commit, good_commit
  ]

  check_output(start_cmd)

  run_cmd = [
      'git', '-C', src_path, 'bisect', 'run',
      os.path.abspath(__file__), '--svn_version',
      '%d' % svn_version, '--patch_metadata_file', patch_metadata_file,
      '--filesdir_path', filesdir_path, '--src_path', src_path,
      '--failure_mode', 'internal_bisection', '--num_patches_to_iterate',
      '%d' % num_patches
  ]

  check_call(run_cmd)

  # Successfully bisected the patch, so retrieve the SVN version from the
  # commit message.
  get_bad_commit_hash_cmd = [
      'git', '-C', src_path, 'rev-parse', 'refs/bisect/bad'
  ]

  git_hash = check_output(get_bad_commit_hash_cmd)

  end_cmd = ['git', '-C', src_path, 'bisect', 'reset']

  check_output(end_cmd)

  # `git bisect run` returns the bad commit hash and the commit message.
  version = get_llvm_hash.GetVersionFrom(src_path, git_hash.rstrip())

  return version


def CleanSrcTree(src_path):
  """Cleans the source tree of the changes made in 'src_path'."""

  reset_src_tree_cmd = ['git', '-C', src_path, 'reset', 'HEAD', '--hard']

  check_output(reset_src_tree_cmd)

  clean_src_tree_cmd = ['git', '-C', src_path, 'clean', '-fd']

  check_output(clean_src_tree_cmd)


def SaveSrcTreeState(src_path):
  """Stashes the changes made so far to the source tree."""

  save_src_tree_cmd = ['git', '-C', src_path, 'stash', '-a']

  check_output(save_src_tree_cmd)


def RestoreSrcTreeState(src_path, bad_commit_hash):
  """Restores the changes made to the source tree."""

  checkout_cmd = ['git', '-C', src_path, 'checkout', bad_commit_hash]

  check_output(checkout_cmd)

  get_changes_cmd = ['git', '-C', src_path, 'stash', 'pop']

  check_output(get_changes_cmd)


def HandlePatches(svn_version,
                  patch_metadata_file,
                  filesdir_path,
                  src_path,
                  mode,
                  good_svn_version=None,
                  num_patches_to_iterate=None,
                  continue_bisection=False):
  """Handles the patches in the .json file for the package.

  Args:
    svn_version: The LLVM version to use for patch management.
    patch_metadata_file: The absolute path to the .json file in '$FILESDIR/'
    that has all the patches and their metadata.
    filesdir_path: The absolute path to $FILESDIR.
    src_path: The absolute path to the unpacked destination of the package.
    mode: The action to take when an applicable patch failed to apply.
      Ex: 'FailureModes.FAIL'
    good_svn_version: Only used by 'bisect_patches' which tells
    `git bisect start` the good version.
    num_patches_to_iterate: The number of patches to iterate in the .JSON file
    (internal use). Only used by `git bisect run`.
    continue_bisection: Only used for 'bisect_patches' mode. If flag is set,
    then bisection will continue to the next patch when successfully bisected a
    patch.

  Returns:
    Depending on the mode, 'None' would be returned if everything went well or
    the .json file was not updated. Otherwise, a list or multiple lists would
    be returned that indicates what has changed.

  Raises:
    ValueError: The patch metadata file does not exist or does not end with
    '.json' or the absolute path to $FILESDIR does not exist or the unpacked
    path does not exist or if the mode is 'fail', then an applicable patch
    failed to apply.
  """

  # A flag for whether the mode specified would possible modify the patches.
  can_modify_patches = False

  # 'fail' or 'continue' mode would not modify a patch's metadata, so the .json
  # file would stay the same.
  if mode != FailureModes.FAIL and mode != FailureModes.CONTINUE:
    can_modify_patches = True

  # A flag that determines whether at least one patch's metadata was
  # updated due to the mode that is passed in.
  updated_patch = False

  # A list of patches that will be in the updated .json file.
  applicable_patches = []

  # A list of patches that successfully applied.
  applied_patches = []

  # A list of patches that were disabled.
  disabled_patches = []

  # A list of bisected patches.
  bisected_patches = []

  # A list of non applicable patches.
  non_applicable_patches = []

  # A list of patches that will not be included in the updated .json file
  removed_patches = []

  # Whether the patch metadata file was modified where 'None' means that the
  # patch metadata file was not modified otherwise the absolute path to the
  # patch metadata file is stored.
  modified_metadata = None

  # A list of patches that failed to apply.
  failed_patches = []

  with open(patch_metadata_file) as patch_file:
    patch_file_contents = json.load(patch_file)

    if mode == FailureModes.BISECT_PATCHES:
      # A good and bad commit are required by `git bisect start`.
      good_commit, bad_commit = GetCommitHashesForBisection(
          src_path, good_svn_version, svn_version)

    # Patch format:
    # {
    #   "rel_patch_path" : "[REL_PATCH_PATH_FROM_$FILESDIR]"
    #   [PATCH_METADATA] if available.
    # }
    #
    # For each patch, find the path to it in $FILESDIR and get its metadata if
    # available, then check if the patch is applicable.
    for patch_dict_index, cur_patch_dict in enumerate(patch_file_contents):
      # Used by the internal bisection. All the patches in the interval [0, N]
      # have been iterated.
      if num_patches_to_iterate and \
          (patch_dict_index + 1) > num_patches_to_iterate:
        break

      # Get the absolute path to the patch in $FILESDIR.
      path_to_patch = GetPathToPatch(filesdir_path,
                                     cur_patch_dict['rel_patch_path'])

      # Get the patch's metadata.
      #
      # Index information of 'patch_metadata':
      #   [0]: start_version
      #   [1]: end_version
      #   [2]: is_critical
      patch_metadata = GetPatchMetadata(cur_patch_dict)

      if not patch_metadata[1]:
        # Patch does not have an 'end_version' value which implies 'end_version'
        # == 'inf' ('svn_version' will always be less than 'end_version'), so
        # the patch is applicable if 'svn_version' >= 'start_version'.
        patch_applicable = svn_version >= patch_metadata[0]
      else:
        # Patch is applicable if 'svn_version' >= 'start_version' &&
        # "svn_version" < "end_version".
        patch_applicable = (svn_version >= patch_metadata[0] and \
                            svn_version < patch_metadata[1])

      if can_modify_patches:
        # Add to the list only if the mode can potentially modify a patch.
        #
        # If the mode is 'remove_patches', then all patches that are
        # applicable or are from the future will be added to the updated .json
        # file and all patches that are not applicable will be added to the
        # remove patches list which will not be included in the updated .json
        # file.
        if patch_applicable or svn_version < patch_metadata[0] or \
            mode != FailureModes.REMOVE_PATCHES:
          applicable_patches.append(cur_patch_dict)
        elif mode == FailureModes.REMOVE_PATCHES:
          removed_patches.append(path_to_patch)

          if not modified_metadata:
            # At least one patch will be removed from the .json file.
            modified_metadata = patch_metadata_file

      if not patch_applicable:
        non_applicable_patches.append(os.path.basename(path_to_patch))

      # There is no need to apply patches in 'remove_patches' mode because the
      # mode removes patches that do not apply anymore based off of
      # 'svn_version.'
      if patch_applicable and mode != FailureModes.REMOVE_PATCHES:
        patch_applied = ApplyPatch(src_path, path_to_patch)

        if not patch_applied:  # Failed to apply patch.
          failed_patches.append(os.path.basename(path_to_patch))

          # Check the mode to determine what action to take on the failing
          # patch.
          if mode == FailureModes.DISABLE_PATCHES:
            # Set the patch's 'end_version' to 'svn_version' so the patch
            # would not be applicable anymore (i.e. the patch's 'end_version'
            # would not be greater than 'svn_version').

            # Last element in 'applicable_patches' is the current patch.
            applicable_patches[-1]['end_version'] = svn_version

            disabled_patches.append(os.path.basename(path_to_patch))

            if not updated_patch:
              # At least one patch has been modified, so the .json file
              # will be updated with the new patch metadata.
              updated_patch = True

              modified_metadata = patch_metadata_file
          elif mode == FailureModes.BISECT_PATCHES:
            # Figure out where the patch's stops applying and set the patch's
            # 'end_version' to that version.

            # Do not want to overwrite the changes to the current progress of
            # 'bisect_patches' on the source tree.
            SaveSrcTreeState(src_path)

            # Need a clean source tree for `git bisect run` to avoid unnecessary
            # fails for patches.
            CleanSrcTree(src_path)

            print('\nStarting to bisect patch %s for SVN version %d:\n' %
                  (os.path.basename(cur_patch_dict['rel_patch_path']),
                   svn_version))

            # Performs the bisection: calls `git bisect start` and
            # `git bisect run`, where `git bisect run` is going to call this
            # script as many times as needed with specific arguments.
            bad_svn_version = PerformBisection(
                src_path, good_commit, bad_commit, svn_version,
                patch_metadata_file, filesdir_path, patch_dict_index + 1)

            print('\nSuccessfully bisected patch %s, starts to fail to apply '
                  'at %d\n' % (os.path.basename(
                      cur_patch_dict['rel_patch_path']), bad_svn_version))

            # Overwrite the .JSON file with the new 'end_version' for the
            # current failed patch so that if there are other patches that
            # fail to apply, then the 'end_version' for the current patch could
            # be applicable when `git bisect run` is performed on the next
            # failed patch because the same .JSON file is used for `git bisect
            # run`.
            patch_file_contents[patch_dict_index][
                'end_version'] = bad_svn_version
            UpdatePatchMetadataFile(patch_metadata_file, patch_file_contents)

            # Clear the changes made to the source tree by `git bisect run`.
            CleanSrcTree(src_path)

            if not continue_bisection:
              # Exiting program early because 'continue_bisection' is not set.
              sys.exit(0)

            bisected_patches.append(
                '%s starts to fail to apply at %d' % (os.path.basename(
                    cur_patch_dict['rel_patch_path']), bad_svn_version))

            # Continue where 'bisect_patches' left off.
            RestoreSrcTreeState(src_path, bad_commit)

            if not modified_metadata:
              # At least one patch's 'end_version' has been updated.
              modified_metadata = patch_metadata_file

          elif mode == FailureModes.FAIL:
            if applied_patches:
              print('The following patches applied successfully up to the '
                    'failed patch:')
              print('\n'.join(applied_patches))

            # Throw an exception on the first patch that failed to apply.
            raise ValueError(
                'Failed to apply patch: %s' % os.path.basename(path_to_patch))
          elif mode == FailureModes.INTERNAL_BISECTION:
            # Determine the exit status for `git bisect run` because of the
            # failed patch in the interval [0, N].
            #
            # NOTE: `git bisect run` exit codes are as follows:
            #   130: Terminates the bisection.
            #   1: Similar as `git bisect bad`.

            # Some patch in the interval [0, N) failed, so terminate bisection
            # (the patch stack is broken).
            if (patch_dict_index + 1) != num_patches_to_iterate:
              print('\nTerminating bisection due to patch %s failed to apply '
                    'on SVN version %d.\n' % (os.path.basename(
                        cur_patch_dict['rel_patch_path']), svn_version))

              # Man page for `git bisect run` states that any value over 127
              # terminates it.
              sys.exit(130)

            # Changes to the source tree need to be removed, otherwise some
            # patches may fail when applying the patch to the source tree when
            # `git bisect run` calls this script again.
            CleanSrcTree(src_path)

            # The last patch in the interval [0, N] failed to apply, so let
            # `git bisect run` know that the last patch (the patch that failed
            # originally which led to `git bisect run` to be invoked) is bad
            # with exit code 1.
            sys.exit(1)
        else:  # Successfully applied patch
          applied_patches.append(os.path.basename(path_to_patch))

  # All patches in the interval [0, N] applied successfully, so let
  # `git bisect run` know that the program exited with exit code 0 (good).
  if mode == FailureModes.INTERNAL_BISECTION:
    # Changes to the source tree need to be removed, otherwise some
    # patches may fail when applying the patch to the source tree when
    # `git bisect run` calls this script again.
    #
    # Also, if `git bisect run` will NOT call this script again (terminated) and
    # if the source tree changes are not removed, `git bisect reset` will
    # complain that the changes would need to be 'stashed' or 'removed' in
    # order to reset HEAD back to the bad commit's git hash, so HEAD will remain
    # on the last git hash used by `git bisect run`.
    CleanSrcTree(src_path)

    # NOTE: Exit code 0 is similar to `git bisect good`.
    sys.exit(0)

  # Create a namedtuple of the patch results.
  PatchInfo = namedtuple('PatchInfo', [
      'applied_patches', 'failed_patches', 'non_applicable_patches',
      'disabled_patches', 'removed_patches', 'modified_metadata'
  ])

  patch_info = PatchInfo(
      applied_patches=applied_patches,
      failed_patches=failed_patches,
      non_applicable_patches=non_applicable_patches,
      disabled_patches=disabled_patches,
      removed_patches=removed_patches,
      modified_metadata=modified_metadata)

  # Determine post actions after iterating through the patches.
  if mode == FailureModes.REMOVE_PATCHES:
    if removed_patches:
      UpdatePatchMetadataFile(patch_metadata_file, applicable_patches)
  elif mode == FailureModes.DISABLE_PATCHES:
    if updated_patch:
      UpdatePatchMetadataFile(patch_metadata_file, applicable_patches)
  elif mode == FailureModes.BISECT_PATCHES:
    PrintPatchResults(patch_info)
    if modified_metadata:
      print('\nThe following patches have been bisected:')
      print('\n'.join(bisected_patches))

    # Exiting early because 'bisect_patches' will not be called from other
    # scripts, only this script uses 'bisect_patches'. The intent is to provide
    # bisection information on the patches and aid in the bisection process.
    sys.exit(0)

  return patch_info


def PrintPatchResults(patch_info):
  """Prints the results of handling the patches of a package.

  Args:
    patch_info: A namedtuple that has information on the patches.
  """

  if patch_info.applied_patches:
    print('\nThe following patches applied successfully:')
    print('\n'.join(patch_info.applied_patches))

  if patch_info.failed_patches:
    print('\nThe following patches failed to apply:')
    print('\n'.join(patch_info.failed_patches))

  if patch_info.non_applicable_patches:
    print('\nThe following patches were not applicable:')
    print('\n'.join(patch_info.non_applicable_patches))

  if patch_info.modified_metadata:
    print('\nThe patch metadata file %s has been modified' % os.path.basename(
        patch_info.modified_metadata))

  if patch_info.disabled_patches:
    print('\nThe following patches were disabled:')
    print('\n'.join(patch_info.disabled_patches))

  if patch_info.removed_patches:
    print('\nThe following patches were removed from the patch metadata file:')
    for cur_patch_path in patch_info.removed_patches:
      print('%s' % os.path.basename(cur_patch_path))


def main():
  """Applies patches to the source tree and takes action on a failed patch."""

  args_output = GetCommandLineArgs()

  if args_output.failure_mode != FailureModes.INTERNAL_BISECTION.value:
    # If the SVN version of HEAD is not the same as 'svn_version', then some
    # patches that fail to apply could successfully apply if HEAD's SVN version
    # was the same as 'svn_version'. In other words, HEAD's git hash should be
    # what is being updated to (e.g. LLVM_NEXT_HASH).
    VerifyHEADIsTheSameAsSVNVersion(args_output.src_path,
                                    args_output.svn_version)
  else:
    # `git bisect run` called this script.
    #
    # `git bisect run` moves HEAD each time it invokes this script, so set the
    # 'svn_version' to be current HEAD's SVN version so that the previous
    # SVN version is not used in determining whether a patch is applicable.
    args_output.svn_version = GetHEADSVNVersion(args_output.src_path)

  # Get the results of handling the patches of the package.
  patch_info = HandlePatches(
      args_output.svn_version, args_output.patch_metadata_file,
      args_output.filesdir_path, args_output.src_path,
      FailureModes(args_output.failure_mode), args_output.good_svn_version,
      args_output.num_patches_to_iterate, args_output.continue_bisection)

  PrintPatchResults(patch_info)


if __name__ == '__main__':
  main()
