#!/usr/bin/env vpython
# Copyright 2017 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.
"""Tool to move Blink source from third_party/WebKit to third_party/blink.

See https://docs.google.com/document/d/1l3aPv1Wx__SpRkdOhvJz8ciEGigNT3wFKv78XiuW0Tw/edit?usp=sharing#heading=h.o225wrxp242h
for the details.
"""

import argparse
import logging
import os
import platform
import re
import sys
from functools import partial

sys.path.append(
    os.path.join(
        os.path.dirname(__file__), '..', 'renderer', 'build', 'scripts'))
from blinkbuild.name_style_converter import NameStyleConverter
from blinkpy.common.checkout.git import Git
from blinkpy.common.path_finder import get_chromium_src_dir
from blinkpy.common.path_finder import get_blink_tools_dir
from blinkpy.common.system.executive import Executive
from blinkpy.common.system.executive import ScriptError
from blinkpy.common.system.filesystem import FileSystem
from blinkpy.common.system.platform_info import PlatformInfo
from plan_blink_move import plan_blink_move
from plan_blink_move import relative_dest

_log = logging.getLogger('move_blink_source')


class FileType(object):
    NONE = 0
    BUILD = 1
    BLINK_BUILD = 2
    OWNERS = 3
    DEPS = 4
    MOJOM = 5
    TYPEMAP = 6
    BLINK_BUILD_PY = 7
    LAYOUT_TESTS_WITH_MOJOM = 8
    BLINK_DEPS = 9

    @staticmethod
    def detect(path):
        slash_dir, basename = os.path.split(path)
        slash_dir = slash_dir.replace(os.path.sep, '/')
        if basename == 'DEPS':
            if 'third_party/WebKit' in path:
                return FileType.BLINK_DEPS
            return FileType.DEPS
        if basename == 'OWNERS':
            return FileType.OWNERS
        if basename.endswith('.mojom'):
            return FileType.MOJOM
        if basename.endswith('.typemap'):
            return FileType.TYPEMAP
        if basename.endswith(
                '.py') and 'third_party/WebKit/Source/build' in slash_dir:
            return FileType.BLINK_BUILD_PY
        if basename.endswith(('.gn', '.gni')):
            if 'third_party/WebKit' in path or 'third_party/blink' in slash_dir:
                return FileType.BLINK_BUILD
            if 'third_party' in slash_dir:
                return FileType.NONE
            return FileType.BUILD
        if basename.endswith('.html') and re.search(
                r'third_party/WebKit/LayoutTests/('
                r'fast/dom/shadow|'
                r'fast/forms/color|'
                r'geolocation-api|'
                r'http/tests/budget|'
                r'http/tests/credentialmanager|'
                r'http/tests/security/powerfulFeatureRestrictions|'
                r'installedapp|'
                r'media/mediasession|'
                r'payments|'
                r'presentation|'
                r'reporting-observer|'
                r'webshare)', slash_dir):
            return FileType.LAYOUT_TESTS_WITH_MOJOM
        return FileType.NONE


class MoveBlinkSource(object):
    def __init__(self, fs, options, repo_root):
        self._fs = fs
        self._platform = PlatformInfo(sys, platform, fs, Executive())
        self._options = options
        _log.debug(options)
        self._repo_root = repo_root

        # The following fields are initialized in _create_basename_maps.
        self._basename_map = None
        self._basename_re_list = None
        self._idl_generated_impl_headers = None
        # _checked_in_header_re_list is used to distinguish checked-in
        # header files and generated header files.
        self._checked_in_header_re_list = None

        self._updated_files = []

    def update(self, apply_only=None):
        """Updates contents of files affected by Blink source move.

        Args:
            apply_only: If it's None, updates all affected files. Otherwise,
                it should be a set of file paths and this function updates
                only the files in |apply_only|.
        """
        _log.info('Planning renaming ...')
        file_pairs = plan_blink_move(self._fs, [])

        self._create_basename_maps(file_pairs)
        dirs = self._update_file_content(apply_only)

        # Updates #includes in files in directories with updated DEPS +
        # third_party/WebKit/{Source,common,public}.
        self._append_unless_upper_dir_exists(
            dirs,
            self._fs.join(self._repo_root, 'third_party', 'WebKit', 'Source'))
        self._append_unless_upper_dir_exists(
            dirs,
            self._fs.join(self._repo_root, 'third_party', 'WebKit', 'common'))
        self._append_unless_upper_dir_exists(
            dirs,
            self._fs.join(self._repo_root, 'third_party', 'WebKit', 'public'))
        self._append_unless_upper_dir_exists(
            dirs,
            self._fs.join(self._repo_root, 'mojo', 'public', 'tools',
                          'bindings', 'generators', 'cpp_templates'))
        self._update_cpp_includes_in_directories(dirs, apply_only)

        # Content update for individual files.
        # The following is a list of tuples.
        #  Tuple: (<file path relative to repo root>, [replacement commands])
        #  Command: a callable object, or
        #           a tuple of (<original string>, <new string>).
        file_replacement_list = [
            ('DEPS', [('src/third_party/WebKit/Source/devtools',
                       'src/third_party/blink/renderer/devtools')]),
            ('WATCHLISTS',
             [('third_party/WebKit/Source', 'third_party/blink/renderer'),
              ('third_party/WebKit/public', 'third_party/blink/public')]),
            ('build/check_gn_headers_whitelist.txt',
             [('third_party/WebKit/Source', 'third_party/blink/renderer'),
              ('third_party/WebKit/public', 'third_party/blink/public'),
              self._update_basename]),
            ('chrome/browser/resources/chromeos/accessibility/chromevox/tools/jsbundler.py',
             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('testing/buildbot/gn_isolate_map.pyl',
             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('third_party/WebKit/Source/BUILD.gn',
             [('$root_gen_dir/third_party/WebKit',
               '$root_gen_dir/third_party/blink')]),
            ('third_party/WebKit/Source/config.gni',
             [('snake_case_source_files = false',
               'snake_case_source_files = true')]),
            ('third_party/WebKit/Source/core/css/CSSProperties.json5',
             [self._update_basename]),
            ('third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5',
             [self._update_basename]),
            ('third_party/WebKit/Source/core/css/ComputedStyleFieldAliases.json5',
             [self._update_basename]),
            ('third_party/WebKit/Source/core/html/parser/create-html-entity-table',
             [self._update_basename]),
            ('third_party/WebKit/Source/core/inspector/inspector_protocol_config.json',
             [self._update_basename]),
            ('third_party/WebKit/Source/core/probe/CoreProbes.json5',
             [self._update_basename]),
            ('third_party/WebKit/Source/core/testing/InternalSettings.h',
             [('InternalSettingsGenerated.h',
               'internal_settings_generated.h')]),
            ('third_party/WebKit/Source/core/testing/Internals.cpp',
             [('InternalRuntimeFlags.h', 'internal_runtime_flags.h')]),
            ('third_party/WebKit/Source/platform/probe/PlatformProbes.json5',
             [self._update_basename]),
            ('third_party/WebKit/Tools/Scripts/audit-non-blink-usage.py',
             [('third_party/WebKit/Source', 'third_party/blink/renderer'),
              ('ls-files third_party/WebKit', 'ls-files third_party/blink')]),
            ('third_party/WebKit/Tools/Scripts/webkitpy/style/checker.py',
             [('Source/', 'renderer/')]),
            ('third_party/WebKit/public/BUILD.gn',
             [('$root_gen_dir/third_party/WebKit',
               '$root_gen_dir/third_party/blink')]),
            ('third_party/WebKit/public/blink_resources.grd',
             [('../Source/', '../renderer/')]),
            ('third_party/blink/tools/compile_devtools_frontend.py',
             [('\'WebKit\', \'Source\'', '\'blink\', \'renderer\'')]),
            ('tools/android/eclipse/.classpath',
             [('third_party/WebKit/public', 'third_party/blink/public')]),
            ('tools/android/loading/cloud/backend/deploy.sh',
             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('tools/android/loading/emulation_unittest.py',
             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('tools/android/loading/options.py',
             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('tools/android/loading/request_track.py',
             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('tools/cfi/blacklist.txt', [('third_party/WebKit/Source',
                                          'third_party/blink/renderer')]),
            ('tools/gritsettings/resource_ids',
             [('third_party/WebKit/public', 'third_party/blink/public'),
              ('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('tools/include_tracer.py', [('third_party/WebKit/Source',
                                          'third_party/blink/renderer')]),
            ('tools/metrics/actions/extract_actions.py',
             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
            ('tools/metrics/histograms/update_editor_commands.py',
             [('third_party/WebKit/Source/core/editing/EditorCommand.cpp',
               'third_party/blink/renderer/core/editing/editor_command.cc')]),
            ('tools/metrics/histograms/update_use_counter_css.py',
             [('third_party/WebKit/Source/core/frame/UseCounter.cpp',
               'third_party/blink/renderer/core/frame/use_counter.cc')]),
            ('tools/metrics/histograms/update_use_counter_feature_enum.py',
             [('third_party/WebKit/public', 'third_party/blink/public')]),
        ]
        for file_path, replacement_list in file_replacement_list:
            if not apply_only or file_path in apply_only:
                self._update_single_file_content(
                    file_path,
                    replacement_list,
                    should_write=self._options.run)

        if self._options.run:
            _log.info('Formatting updated %d files ...',
                      len(self._updated_files))
            git = self._create_git()
            # |git cl format| can't handle too many files at once.
            while len(self._updated_files) > 0:
                end_index = 100
                if end_index > len(self._updated_files):
                    end_index = len(self._updated_files)
                git.run(['cl', 'format'] + self._updated_files[:end_index])
                self._updated_files = self._updated_files[end_index:]

            if not apply_only:
                _log.info('Make a local commit ...')
                git.commit_locally_with_message(
                    """The Great Blink mv for source files, part 1.

Update file contents without moving files.

NOAUTOREVERT=true
NOPRESUBMIT=true
NOTREECHECKS=true
Bug: 768828
""")

    def move(self, apply_only=None):
        """Move Blink source files.

        Args:
            apply_only: If it's None, move all affected files. Otherwise,
                it should be a set of file paths and this function moves
                only the files in |apply_only|.
        """
        _log.info('Planning renaming ...')
        file_pairs = plan_blink_move(self._fs, [])

        if apply_only:
            file_pairs = [
                (src, dest) for (src, dest) in file_pairs
                if 'third_party/WebKit/' + src.replace('\\', '/') in apply_only
            ]
        _log.info('Will move %d files', len(file_pairs))

        git = self._create_git()
        files_set = self._get_checked_in_files(git)
        for i, (src, dest) in enumerate(file_pairs):
            src_from_repo = self._fs.join('third_party', 'WebKit', src)
            if src_from_repo.replace('\\', '/') not in files_set:
                _log.info('%s is not in the repository', src)
                continue
            dest_from_repo = self._fs.join('third_party', 'blink', dest)
            self._fs.maybe_make_directory(self._repo_root, 'third_party',
                                          'blink', self._fs.dirname(dest))
            if self._options.run_git:
                git.move(src_from_repo, dest_from_repo)
                _log.info('[%d/%d] Git moved %s', i + 1, len(file_pairs), src)
            else:
                self._fs.move(
                    self._fs.join(self._repo_root, src_from_repo),
                    self._fs.join(self._repo_root, dest_from_repo))
                _log.info('[%d/%d] Moved %s', i + 1, len(file_pairs), src)
        if apply_only:
            return

        self._update_single_file_content('build/get_landmines.py', [(
            '\ndef main',
            '  print \'The Great Blink mv for source files (crbug.com/768828)\'\n\ndef main'
        )])

        _log.info('Run run_bindings_tests.py ...')
        Executive().run_command([
            'python',
            self._fs.join(get_blink_tools_dir(), 'run_bindings_tests.py'),
            '--reset-results'
        ],
                                cwd=self._repo_root)

        if self._options.run_git:
            _log.info('Make a local commit ...')
            git.commit_locally_with_message(
                """The Great Blink mv for source files, part 2.

Move and rename files.

NOAUTOREVERT=true
NOPRESUBMIT=true
NOTREECHECKS=true
Bug: 768828
""")

    def fix_branch(self):
        git = self._create_git()
        status = self._get_local_change_status(git)
        if len(status) == 0:
            _log.info('No local changes.')
            return
        modified_files = {f for (s, f) in status if s != 'D'}
        deleted_files = {f for (s, f) in status if s == 'D'}

        self.update(apply_only=modified_files)
        self.move(apply_only=modified_files)
        try:
            git.commit_locally_with_message('This commit should be squashed.')
        except ScriptError:
            _log.info('move_blink_source.py modified nothing.')

        # TODO(tkent): Show a message about deleted_files.

    def _get_local_change_status(self, git):
        """Returns a list of tuples representing local change summary.

        Each tuple contains two strings. The first one is file change status
        such as "M", "D".  See --diff-filter section of git-diff manual page.
        The second one is file name relative to the repository top.
        """

        base_commit = git.run(
            ['show-branch', '--merge-base', 'master', 'HEAD']).strip()
        # Note that file names in the following command result are always
        # slash-separated, even on Windows.
        status_lines = git.run(
            ['diff', '--name-status', '--no-renames', base_commit]).split('\n')
        status_tuple_list = []
        for l in status_lines:
            items = l.split('\t')
            if len(items) == 2:
                status_tuple_list.append(tuple(items))
            elif len(l) > 0:
                _log.warning('Unrecognized diff output: "%s"', l)
        return status_tuple_list

    def _get_checked_in_files(self, git):
        files_text = git.run([
            'ls-files', 'third_party/WebKit/Source',
            'third_party/WebKit/common', 'third_party/WebKit/public'
        ])
        return set(files_text.split('\n'))

    def _create_basename_maps(self, file_pairs):
        basename_map = {}
        basenames = []
        idl_headers = set()
        headers = []
        for source, dest in file_pairs:
            _, source_base = self._fs.split(source)
            _, dest_base = self._fs.split(dest)
            # OriginTrialFeaturesForCore.h in bindings/tests/results/modules/
            # confuses generated/checked-in detection in _replace_include_path().
            if 'bindings/tests' in source.replace('\\', '/'):
                continue
            if source_base.endswith('.h'):
                headers.append(re.escape(source_base))
            if source_base == dest_base:
                continue
            basename_map[source_base] = dest_base
            basenames.append(re.escape(source_base))
            # IDL sometimes generates implementation files as well as
            # binding files. We'd like to update #includes for such files.
            if source_base.endswith('.idl'):
                source_header = source_base.replace('.idl', '.h')
                basename_map[source_header] = dest_base.replace('.idl', '.h')
                basenames.append(re.escape(source_header))
                idl_headers.add(source_header)
            elif source_base.endswith('.proto'):
                source_header = source_base.replace('.proto', '.pb.h')
                basename_map[source_header] = dest_base.replace(
                    '.proto', '.pb.h')
                basenames.append(re.escape(source_header))
        _log.debug('Rename %d files for snake_case', len(basename_map))
        self._basename_map = basename_map
        self._idl_generated_impl_headers = idl_headers

        self._basename_re_list = []
        self._checked_in_header_re_list = []
        # Split file names into some chunks to avoid "Regular expression
        # code size limit exceeded" on Windows
        CHUNK_SIZE = 700
        # Generated inspector/protocol/* contains a lot of names duplicated with
        # checked-in core files. We don't want to rename them, and don't want to
        # replace them in BUILD.gn and #include accidentally.
        RE_PREFIX = r'(?<!inspector/protocol/)'

        while len(basenames) > 0:
            end_index = min(CHUNK_SIZE, len(basenames))
            self._basename_re_list.append(
                re.compile(RE_PREFIX + r'\b(' +
                           '|'.join(basenames[0:end_index]) + ')(?=["\']|$)'))
            basenames = basenames[end_index:]

        while len(headers) > 0:
            end_index = min(CHUNK_SIZE, len(headers))
            self._checked_in_header_re_list.append(
                re.compile(RE_PREFIX + r'\b(' +
                           '|'.join(headers[0:end_index]) + ')$'))
            headers = headers[end_index:]

    def _shorten_path(self, path):
        if path.startswith(self._repo_root):
            return path[len(self._repo_root) + 1:]
        return path

    @staticmethod
    def _filter_file(fs, dirname, basename):
        return FileType.detect(fs.join(dirname, basename)) != FileType.NONE

    def _update_build(self, content):
        content = content.replace('//third_party/WebKit/Source',
                                  '//third_party/blink/renderer')
        content = content.replace('//third_party/WebKit/common',
                                  '//third_party/blink/common')
        content = content.replace('//third_party/WebKit/public',
                                  '//third_party/blink/public')
        # export_header_blink exists outside of Blink too.
        content = content.replace(
            'export_header_blink = "third_party/WebKit/public/platform/WebCommon.h"',
            'export_header_blink = "third_party/blink/public/platform/web_common.h"'
        )
        content = content.replace('$root_gen_dir/blink/public',
                                  '$root_gen_dir/third_party/blink/public')
        content = content.replace('$root_gen_dir/blink',
                                  '$root_gen_dir/third_party/blink/renderer')
        return content

    def _update_blink_build(self, content):
        content = self._update_build(content)

        # Update visibility=[...]
        content = content.replace('//third_party/WebKit/*',
                                  '//third_party/blink/*')
        content = content.replace('//third_party/WebKit/Source/*',
                                  '//third_party/blink/renderer/*')
        content = content.replace('//third_party/WebKit/public/*',
                                  '//third_party/blink/public/*')

        # Update mojom variables
        content = content.replace('export_header = "third_party/WebKit/common',
                                  'export_header = "third_party/blink/common')
        content = content.replace(
            'export_header_blink = "third_party/WebKit/Source',
            'export_header_blink = "third_party/blink/renderer')

        # Update buildflag_header() rules
        content = content.replace('header_dir = "blink/',
                                  'header_dir = "third_party/blink/renderer/')

        return self._update_basename(content)

    def _update_owners(self, content):
        content = content.replace('//third_party/WebKit/Source',
                                  '//third_party/blink/renderer')
        content = content.replace('//third_party/WebKit/common',
                                  '//third_party/blink/common')
        content = content.replace('//third_party/WebKit/public',
                                  '//third_party/blink/public')
        return content

    def _update_deps(self, content):
        original_content = content
        content = content.replace('third_party/WebKit/Source',
                                  'third_party/blink/renderer')
        content = content.replace('third_party/WebKit/common',
                                  'third_party/blink/common')
        content = content.replace('third_party/WebKit/public',
                                  'third_party/blink/public')
        content = content.replace('third_party/WebKit', 'third_party/blink')
        if original_content == content:
            return content
        return self._update_basename(content)

    def _update_blink_deps(self, content):
        original_content = content
        content = re.sub('(?<=[-+!])public', 'third_party/blink/public',
                         content)
        content = re.sub(
            '(?<=[-+!])(bindings|controller|core|modules|platform)',
            'third_party/blink/renderer/\\1', content)
        content = content.replace('third_party/WebKit', 'third_party/blink')
        if original_content == content:
            return content
        return self._update_basename(content)

    def _update_mojom(self, content):
        content = content.replace('third_party/WebKit/public',
                                  'third_party/blink/public')
        content = content.replace('third_party/WebKit/common',
                                  'third_party/blink/common')
        return content

    def _update_typemap(self, content):
        content = content.replace('//third_party/WebKit/Source',
                                  '//third_party/blink/renderer')
        content = content.replace('//third_party/WebKit/common',
                                  '//third_party/blink/common')
        content = content.replace('//third_party/WebKit/public',
                                  '//third_party/blink/public')
        return self._update_basename(content)

    def _update_blink_build_py(self, content):
        # We don't prepend 'third_party/blink/renderer/' to matched basenames
        # because it won't affect build and manual update after the great mv is
        # enough.
        return self._update_basename(content)

    def _update_layout_tests(self, content):
        return content.replace('file:///gen/third_party/WebKit/public/',
                               'file:///gen/third_party/blink/public/')

    def _update_basename(self, content):
        for regex in self._basename_re_list:
            content = regex.sub(
                lambda match: self._basename_map[match.group(1)], content)
        return content

    @staticmethod
    def _append_unless_upper_dir_exists(dirs, new_dir):
        for i in range(0, len(dirs)):
            if new_dir.startswith(dirs[i]):
                return
            if dirs[i].startswith(new_dir):
                dirs[i] = new_dir
                return
        dirs.append(new_dir)

    def _update_file_content(self, apply_only):
        _log.info('Find *.gn, *.mojom, *.py, *.typemap, DEPS, and OWNERS ...')
        files = self._fs.files_under(
            self._repo_root,
            dirs_to_skip=['.git', 'out'],
            file_filter=self._filter_file)
        _log.info('Scan contents of %d files ...', len(files))
        updated_deps_dirs = []
        for file_path in files:
            file_type = FileType.detect(file_path)
            original_content = self._fs.read_text_file(file_path)
            content = original_content
            if file_type == FileType.BUILD:
                content = self._update_build(content)
            elif file_type == FileType.BLINK_BUILD:
                content = self._update_blink_build(content)
            elif file_type == FileType.OWNERS:
                content = self._update_owners(content)
            elif file_type == FileType.DEPS:
                if self._fs.dirname(file_path) == self._repo_root:
                    _log.debug("Skip //DEPS")
                    continue
                content = self._update_deps(content)
            elif file_type == FileType.BLINK_DEPS:
                content = self._update_blink_deps(content)
            elif file_type == FileType.MOJOM:
                content = self._update_mojom(content)
            elif file_type == FileType.TYPEMAP:
                content = self._update_typemap(content)
            elif file_type == FileType.BLINK_BUILD_PY:
                content = self._update_blink_build_py(content)
            elif file_type == FileType.LAYOUT_TESTS_WITH_MOJOM:
                content = self._update_layout_tests(content)

            if original_content == content:
                continue
            if self._options.run and (not apply_only or file_path.replace(
                    '\\', '/') in apply_only):
                self._fs.write_text_file(file_path, content)
                self._updated_files.append(file_path)
                _log.info('Updated %s', self._shorten_path(file_path))
            if file_type == FileType.DEPS:
                self._append_unless_upper_dir_exists(
                    updated_deps_dirs, self._fs.dirname(file_path))
        return updated_deps_dirs

    def _update_cpp_includes_in_directories(self, dirs, apply_only):
        for dirname in dirs:
            _log.info('Processing #include in %s ...',
                      self._shorten_path(dirname))
            files = self._fs.files_under(
                dirname,
                file_filter=
                lambda fs, _, basename: basename.endswith(('.h', '.cc', '.cpp', '.mm', '.cc.tmpl', '.cpp.tmpl', '.h.tmpl', 'xpath_grammar.y', '.gperf'))
            )
            for file_path in files:
                posix_file_path = file_path.replace('\\', '/')
                if '/third_party/WebKit/Source/bindings/tests/results/' in posix_file_path:
                    continue
                original_content = self._fs.read_text_file(file_path)

                content = self._update_cpp_includes(original_content)
                if file_path.endswith(
                        '.h'
                ) and '/third_party/WebKit/public/' in posix_file_path:
                    content = self._update_basename_only_includes(
                        content, file_path)
                if file_path.endswith(
                        '.h') and '/third_party/WebKit/' in posix_file_path:
                    content = self._update_include_guard(content, file_path)

                if original_content == content:
                    continue
                if self._options.run and (not apply_only
                                          or posix_file_path in apply_only):
                    self._fs.write_text_file(file_path, content)
                    self._updated_files.append(file_path)
                    _log.info('Updated %s', self._shorten_path(file_path))

    def _replace_include_path(self, match):
        include_or_import = match.group(1)
        path = match.group(2)

        # If |path| starts with 'blink/public/resources', we should prepend
        # 'third_party/'.
        #
        # If |path| starts with 'third_party/WebKit', we should adjust the
        # directory name for third_party/blink, and replace its basename by
        # self._basename_map.
        #
        # If |path| starts with a Blink-internal directory such as bindings,
        # core, modules, platform, public, it refers to a checked-in file, or a
        # generated file. For the former, we should add 'third_party/blink/' and
        # replace the basename.  For the latter, we should update the basename
        # for a name mapped from an IDL renaming, and should add
        # 'third_party/blink/'.

        if path.startswith('blink/public/resources'):
            path = path.replace('blink/public', 'third_party/blink/public')
            return '#%s "%s"' % (include_or_import, path)

        if path.startswith('third_party/WebKit'):
            path = path.replace('third_party/WebKit/Source',
                                'third_party/blink/renderer')
            path = path.replace('third_party/WebKit/common',
                                'third_party/blink/common')
            path = path.replace('third_party/WebKit/public',
                                'third_party/blink/public')
            path = self._update_basename(path)
            return '#%s "%s"' % (include_or_import, path)

        match = None
        for regex in self._checked_in_header_re_list:
            match = regex.search(path)
            if match:
                break
        if match:
            if match.group(1) in self._basename_map:
                path = path[:match.start(1)] + self._basename_map[match.group(
                    1)]
        elif 'core/inspector/protocol/' not in path:
            basename_start = path.rfind('/') + 1
            basename = path[basename_start:]
            if basename in self._idl_generated_impl_headers:
                path = path[:basename_start] + self._basename_map[basename]
            elif basename.startswith('V8'):
                path = path[:basename_start] + NameStyleConverter(
                    basename[:len(basename) - 2]).to_snake_case() + '.h'
        if path.startswith('public'):
            path = 'third_party/blink/' + path
        else:
            path = 'third_party/blink/renderer/' + path
        return '#%s "%s"' % (include_or_import, path)

    def _update_cpp_includes(self, content):
        pattern = re.compile(
            r'#(include|import)\s+"((bindings|controller|core|modules|platform|public|'
            +
            r'third_party/WebKit/(Source|common|public)|blink/public/resources)/[-_\w/.]+)"'
        )
        return pattern.sub(self._replace_include_path, content)

    def _replace_basename_only_include(self, subdir, source_path, match):
        source_basename = match.group(1)
        if source_basename in self._basename_map:
            return '#include "third_party/blink/public/%s/%s"' % (
                subdir, self._basename_map[source_basename])
        _log.warning('Basename-only %s in %s', match.group(0),
                     self._shorten_path(source_path))
        return match.group(0)

    def _update_basename_only_includes(self, content, source_path):
        if not source_path.endswith(
                '.h'
        ) or '/third_party/WebKit/public/' not in source_path.replace(
                '\\', '/'):
            return
        # In public/ header files, we should replace |#include "WebFoo.h"|
        # with |#include "third_party/blink/public/platform-or-web/web_foo.h"|
        subdir = self._fs.basename(self._fs.dirname(source_path))
        # subdir is 'web' or 'platform'.
        return re.sub(
            r'#include\s+"(\w+\.h)"',
            partial(self._replace_basename_only_include, subdir, source_path),
            content)

    def _update_include_guard(self, content, source_path):
        current_guard = re.sub(r'[-.]', '_', self._fs.basename(source_path))
        new_path = relative_dest(
            self._fs,
            self._fs.relpath(
                source_path,
                start=self._fs.join(self._repo_root, 'third_party', 'WebKit')))
        new_guard = 'THIRD_PARTY_BLINK_' + re.sub(r'[-\\/.]', '_',
                                                  new_path.upper()) + '_'
        content = re.sub(r'#ifndef\s+(WTF_)?' + current_guard,
                         '#ifndef ' + new_guard, content)
        content = re.sub(r'#define\s+(WTF_)?' + current_guard,
                         '#define ' + new_guard, content)
        content = re.sub(r'#endif\s+//\s+(WTF_)?' + current_guard,
                         '#endif  // ' + new_guard, content)
        return content

    def _update_single_file_content(self,
                                    file_path,
                                    replace_list,
                                    should_write=True):
        full_path = self._fs.join(self._repo_root, file_path)
        original_content = self._fs.read_text_file(full_path)
        content = original_content
        for command in replace_list:
            if isinstance(command, tuple):
                src, dest = command
                content = content.replace(src, dest)
            elif callable(command):
                content = command(content)
            else:
                raise TypeError('A tuple or a function is expected.')
        if content != original_content:
            if should_write:
                self._fs.write_text_file(full_path, content)
                self._updated_files.append(full_path)
                _log.info('Updated %s', file_path)
        else:
            _log.warning('%s does not contain specified source strings.',
                         file_path)

    def _create_git(self):
        return Git(
            cwd=self._repo_root, filesystem=self._fs, platform=self._platform)


def main():
    logging.basicConfig(
        level=logging.INFO,
        format='[%(asctime)s %(levelname)s %(name)s] %(message)s',
        datefmt='%H:%M:%S')
    parser = argparse.ArgumentParser(description='Blink source mover')
    sub_parsers = parser.add_subparsers()

    update_parser = sub_parsers.add_parser('update')
    update_parser.set_defaults(command='update')
    update_parser.add_argument(
        '--run', dest='run', action='store_true', help='Update file contents')

    move_parser = sub_parsers.add_parser('move')
    move_parser.set_defaults(command='move')
    move_parser.add_argument(
        '--git',
        dest='run_git',
        action='store_true',
        help='Run |git mv| command instead of |mv|.')

    fixbranch_parser = sub_parsers.add_parser('fixbranch')
    fixbranch_parser.set_defaults(command='fixbranch', run=True, run_git=True)

    options = parser.parse_args()
    mover = MoveBlinkSource(FileSystem(), options, get_chromium_src_dir())
    if options.command == 'update':
        mover.update()
    elif options.command == 'move':
        mover.move()
    elif options.command == 'fixbranch':
        mover.fix_branch()


if __name__ == '__main__':
    main()
