#!/usr/bin/env python

import glob
import os
from pathlib import Path


class Copyright:
    NOTICE = """Licensed to the Software Freedom Conservancy (SFC) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The SFC licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License."""

    def __init__(self, comment_characters="//", prefix=None):
        self._comment_characters = comment_characters
        self._prefix = prefix or []

    def update(self, files):
        for file in files:
            with open(file, encoding="utf-8-sig") as f:
                lines = f.readlines()

            index = -1
            for i, line in enumerate(lines):
                if line.startswith(self._comment_characters) or self.valid_copyright_notice_line(line, index, file):
                    index += 1
                else:
                    break

            if index == -1:
                self.write_update_notice(file, lines)
            else:
                current = "".join(lines[: index + 1])
                if current != self.copyright_notice(file):
                    self.write_update_notice(file, lines[index + 1 :])

    def valid_copyright_notice_line(self, line, index, file):
        return index + 1 < len(self.copyright_notice_lines(file)) and line.startswith(
            self.copyright_notice_lines(file)[index + 1]
        )

    def copyright_notice(self, file):
        return "".join(self.copyright_notice_lines(file))

    def copyright_notice_lines(self, file):
        return self.dotnet(file) if file.endswith("cs") else self._prefix + self.commented_notice_lines

    def dotnet(self, file):
        file_name = os.path.basename(file)
        first = f'{self._comment_characters} <copyright file="{file_name}" company="Selenium Committers">\n'
        last = f"{self._comment_characters} </copyright>"
        return [first] + self.commented_notice_lines + [last]

    @property
    def commented_notice_lines(self):
        return [f"{self._comment_characters} {line}".rstrip() + "\n" for line in self.NOTICE.split("\n")]

    def write_update_notice(self, file, lines):
        # Build new content
        new_content = self.copyright_notice(file) + "\n"
        if lines and lines[0] != "\n":
            new_content += "\n"
        new_content += "".join(line.rstrip() + "\n" for line in lines)

        # Only write if different
        with open(file, encoding="utf-8-sig") as f:
            old_content = f.read()
        if new_content == old_content:
            return

        print(f"Adding notice to {file}")
        with open(file, "w") as f:
            f.write(new_content)


ROOT = Path(os.path.realpath(__file__)).parent.parent

JS_EXCLUSIONS = [
    f"{ROOT}/javascript/atoms/test/jquery.min.js",
    f"{ROOT}/javascript/jsunit/**/*.js",
    f"{ROOT}/javascript/selenium-webdriver/node_modules/**/*.js",
    f"{ROOT}/javascript/selenium-core/lib/**/*.js",
    f"{ROOT}/javascript/selenium-core/scripts/ui-element.js",
    f"{ROOT}/javascript/selenium-core/scripts/ui-map-sample.js",
    f"{ROOT}/javascript/selenium-core/scripts/user-extensions.js",
    f"{ROOT}/javascript/selenium-core/scripts/xmlextras.js",
    f"{ROOT}/javascript/selenium-core/xpath/**/*.js",
    f"{ROOT}/javascript/grid-ui/node_modules/**/*.js",
    f"{ROOT}/javascript/node/selenium-webdriver/node_modules/**/*.js",
]

PY_EXCLUSIONS = [
    f"{ROOT}/py/generate.py",
    f"{ROOT}/py/selenium/webdriver/common/devtools/**/*",
    f"{ROOT}/py/venv/**/*",
]


def update_files(file_pattern, exclusions, comment_characters="//", prefix=None):
    included = set(glob.glob(file_pattern, recursive=True))
    excluded = set()
    for pattern in exclusions:
        excluded.update(glob.glob(pattern, recursive=True))
    files = included - excluded

    copyright = Copyright(comment_characters, prefix)
    copyright.update(files)


if __name__ == "__main__":
    update_files(f"{ROOT}/javascript/**/*.js", JS_EXCLUSIONS)
    update_files(f"{ROOT}/javascript/**/*.tsx", [])
    update_files(f"{ROOT}/py/**/*.py", PY_EXCLUSIONS, comment_characters="#")
    update_files(
        f"{ROOT}/rb/**/*.rb",
        [],
        comment_characters="#",
        prefix=["# frozen_string_literal: true\n", "\n"],
    )
    update_files(f"{ROOT}/java/**/*.java", [])
    update_files(f"{ROOT}/rust/**/*.rs", [])
    update_files(f"{ROOT}/dotnet/**/*.cs", [])
