#!/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


CHROMIUM_REGEX = r'(chromium.googlesource.com[^\s]*\/\+\/)(master)'
CHROMIUM_REGEX_ALT =\
    r'(chromium.googlesource.com[^\s]*\/\+\/)(refs\/heads\/master)'
GITHUB_REGEX = r'(github.com[^\s]*\/)(master)'
DEFAULT_REPL_PATTERN = r'\1HEAD'

PATTERNS = [
    Pattern(match_pattern=CHROMIUM_REGEX, repl_pattern=DEFAULT_REPL_PATTERN),
    Pattern(match_pattern=CHROMIUM_REGEX_ALT,
            repl_pattern=DEFAULT_REPL_PATTERN),
    Pattern(match_pattern=GITHUB_REGEX, repl_pattern=DEFAULT_REPL_PATTERN),
]


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())
