#!/usr/bin/env python
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function
import argparse
import sys
import os
import subprocess
import glob
import shutil


FILES_TO_SYNC = [
    'README.md',
    'check_protocol_compatibility.py',
    'code_generator.py',
    'concatenate_protocols.py',
    'convert_protocol_to_json.py',
    'encoding/encoding.h',
    'encoding/encoding.cc',
    'encoding/encoding_test.cc',
    'bindings/bindings.h',
    'bindings/bindings.cc',
    'bindings/bindings_test.cc',
    'inspector_protocol.gni',
    'inspector_protocol.gypi',
    'lib/*',
    'pdl.py',
    'templates/*',
]


def RunCmd(cmd):
  p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
  (stdoutdata, stderrdata) = p.communicate()
  if p.returncode != 0:
    raise Exception('%s: exit status %d', str(cmd), p.returncode)
  return stdoutdata


def CheckRepoIsClean(path, suffix):
  os.chdir(path)  # As a side effect this also checks for existence of the dir.
  # If path isn't a git repo, this will throw and exception.
  # And if it is a git repo and 'git status' has anything interesting to say,
  # then it's not clean (uncommitted files etc.)
  if len(RunCmd(['git', 'status', '--porcelain'])) != 0:
    raise Exception('%s is not a clean git repo (run git status)' % path)
  if not path.endswith(suffix):
    raise Exception('%s does not end with /%s' % (path, suffix))


def CheckRepoIsNotAtMasterBranch(path):
  os.chdir(path)
  stdout = RunCmd(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
  if stdout == 'master':
    raise Exception('%s is at master branch - refusing to copy there.' % path)


def CheckRepoIsV8Checkout(path):
  os.chdir(path)
  if (RunCmd(['git', 'config', '--get', 'remote.origin.url']).strip() !=
      'https://chromium.googlesource.com/v8/v8.git'):
    raise Exception('%s is not a proper V8 checkout.' % path)


def CheckRepoIsInspectorProtocolCheckout(path):
  os.chdir(path)
  if (RunCmd(['git', 'config', '--get', 'remote.origin.url']).strip() !=
      'https://chromium.googlesource.com/deps/inspector_protocol.git'):
    raise Exception('%s is not a proper inspector_protocol checkout.' % path)


def FindFilesToSyncIn(path):
  files = []
  for f in FILES_TO_SYNC:
    files += glob.glob(os.path.join(path, f))
  files = [os.path.relpath(f, path) for f in files]
  return files


def FilesAreEqual(path1, path2):
  # We check for permissions (useful for executable scripts) and contents.
  return (os.stat(path1).st_mode == os.stat(path2).st_mode and
          open(path1).read() == open(path2).read())


def GetHeadRevision(path):
  os.chdir(path)
  return RunCmd(['git', 'rev-parse', 'HEAD'])


def main(argv):
  parser = argparse.ArgumentParser(description=(
      "Rolls the inspector_protocol project (upstream) into V8's "
      "third_party (downstream)."))
  parser.add_argument("--ip_src_upstream",
                      help="The inspector_protocol (upstream) tree.",
                      default="~/ip/src")
  parser.add_argument("--v8_src_downstream",
                      help="The V8 src tree.",
                      default="~/v8/v8")
  parser.add_argument('--force', dest='force', action='store_true',
                      help=("Whether to carry out the modifications "
                            "in the destination tree."))
  parser.set_defaults(force=False)

  args = parser.parse_args(argv)
  upstream = os.path.normpath(os.path.expanduser(args.ip_src_upstream))
  downstream = os.path.normpath(os.path.expanduser(
      args.v8_src_downstream))
  CheckRepoIsClean(upstream, '/src')
  CheckRepoIsClean(downstream, '/v8')
  CheckRepoIsInspectorProtocolCheckout(upstream)
  CheckRepoIsV8Checkout(downstream)
  # Check that the destination Git repo isn't at the master branch - it's
  # generally a bad idea to check into the master branch, so we catch this
  # common pilot error here early.
  CheckRepoIsNotAtMasterBranch(downstream)
  src_dir = upstream
  dest_dir = os.path.join(downstream, 'third_party/inspector_protocol')
  print('Rolling %s into %s ...' % (src_dir, dest_dir))
  src_files = set(FindFilesToSyncIn(src_dir))
  dest_files = set(FindFilesToSyncIn(dest_dir))
  to_add = [f for f in src_files if f not in dest_files]
  to_delete = [f for f in dest_files if f not in src_files]
  to_copy = [f for f in src_files
             if (f in dest_files and not FilesAreEqual(
                 os.path.join(src_dir, f), os.path.join(dest_dir, f)))]
  print('To add: %s' % to_add)
  print('To delete: %s' % to_delete)
  print('To copy: %s' % to_copy)
  if not to_add and not to_delete and not to_copy:
    print('Nothing to do. You\'re good.')
    sys.exit(0)
  if not args.force:
    print('Rerun with --force if you wish the modifications to be done.')
    sys.exit(1)
  print('You said --force ... as you wish, modifying the destination.')
  for f in to_add + to_copy:
    contents = open(os.path.join(src_dir, f)).read()
    contents = contents.replace(
        'INSPECTOR_PROTOCOL_ENCODING_ENCODING_H_',
        'V8_INSPECTOR_PROTOCOL_ENCODING_ENCODING_H_')
    contents = contents.replace(
        'namespace inspector_protocol_encoding',
        'namespace v8_inspector_protocol_encoding')
    contents = contents.replace(
        'INSPECTOR_PROTOCOL_BINDINGS_BINDINGS_H_',
        'V8_INSPECTOR_PROTOCOL_BINDINGS_BINDINGS_H_')
    contents = contents.replace(
        'namespace inspector_protocol_bindings',
        'namespace v8_inspector_protocol_bindings')
    open(os.path.join(dest_dir, f), 'w').write(contents)
    shutil.copymode(os.path.join(src_dir, f), os.path.join(dest_dir, f))
  for f in to_delete:
    os.unlink(os.path.join(dest_dir, f))
  head_revision = GetHeadRevision(upstream)
  lines = open(os.path.join(dest_dir, 'README.v8')).readlines()
  f = open(os.path.join(dest_dir, 'README.v8'), 'w')
  for line in lines:
    if line.startswith('Revision: '):
      f.write('Revision: %s' % head_revision)
    else:
      f.write(line)
  f.close()


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
