#!/usr/bin/env python3

# Copyright 2020 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.

"""Fixes common URLs for COIL.
"""
import argparse
import logging
import re
import shutil
import subprocess
import sys
import tempfile


class Pattern:
    def __init__(self, match_pattern, repl_pattern):
        self.match_pattern = match_pattern
        self.repl_pattern = repl_pattern


DEFAULT_REGEX_PATTERN = r'({DOMAIN}[^\s]*\/\+\/)(master)'
ALT_REGEX_PATTERN = r'({DOMAIN}[^\s]*\/\+\/)(refs\/heads\/master)'

GOOGLESOURCE = 'googlesource.com'
SOURCE_CHROMIUM_ORG = 'source.chromium.org'

GOOGLESOURCE_REGEX = DEFAULT_REGEX_PATTERN.format(DOMAIN=GOOGLESOURCE)
GOOGLESOURCE_REGEX_ALT = ALT_REGEX_PATTERN.format(DOMAIN=GOOGLESOURCE)
CHROMIUM_SOURCE_REGEX = DEFAULT_REGEX_PATTERN.format(DOMAIN=SOURCE_CHROMIUM_ORG)
CHROMIUM_SOURCE_REGEX_ALT = ALT_REGEX_PATTERN.format(DOMAIN=SOURCE_CHROMIUM_ORG)
GITHUB_REGEX = r'(github.com[^\s]*\/)(master)'
DEFAULT_REPL_PATTERN = r'\1HEAD'

DOMAINS = [
    GOOGLESOURCE_REGEX,
    GOOGLESOURCE_REGEX_ALT,
    CHROMIUM_SOURCE_REGEX,
    CHROMIUM_SOURCE_REGEX_ALT,
    GITHUB_REGEX,
]

PATTERNS = [
    Pattern(match_pattern=x,
            repl_pattern=DEFAULT_REPL_PATTERN) for x in DOMAINS]


def fix_line(text: str):
    # iterate through patterns. if line is changed, return
    for pattern in PATTERNS:
        new_str, count = re.subn(pattern.match_pattern, pattern.repl_pattern,
                                 text)
        if count > 0:
            return new_str

    return text


def fix_file(file: str):
    try:
        with tempfile.NamedTemporaryFile() as tmp_file:
            logging.debug('created temp file: %s', tmp_file.name)

            # replace line-by-line
            with open(file) as orig_file:
                for line in orig_file:
                    newline = fix_line(line)

                    # write newline to temp file
                    tmp_file.write(newline.encode())

            # replace orig with temp file
            tmp_file.flush()
            shutil.copyfile(tmp_file.name, file)
    except UnicodeDecodeError:
        # skip any files that aren't utf8
        pass


def is_git_dir():
    cmd = [
        'git', 'rev-parse', '--git-dir'
    ]
    logging.debug('Running command: "%s"', ' '.join(cmd))
    ret = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return ret.returncode == 0


def find_files():
    git_cmd = ['git', 'grep', '--name-only']
    grep_cmd = ['grep', '-r', '--files-with-matches']

    if is_git_dir():
        cmd = git_cmd
    else:
        cmd = grep_cmd

    cmd.append('master')
    logging.debug('Running command: "%s"', ' '.join(cmd))
    ret = subprocess.run(cmd, stdout=subprocess.PIPE, check=True)
    return ret.stdout.decode().splitlines()


def main():
    parser = argparse.ArgumentParser()

    log_level_choices = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
    parser.add_argument(
        '--log_level', '-l',
        choices=log_level_choices,
        default='INFO'
    )

    args = parser.parse_args()
    logging.basicConfig(level=args.log_level)

    for file_name in find_files():
        fix_file(file_name)

    sys.exit(0)


if __name__ == '__main__':
    sys.exit(main())
