#!/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, "r", 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):
        print(f"Adding notice to {file}")
        with open(file, "w") as f:
            f.write(self.copyright_notice(file) + "\n")
            if lines and lines[0] != "\n":
                f.write("\n")
            trimmed_lines = [line.rstrip() + "\n" for line in lines]
            f.writelines(trimmed_lines)


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/selenium/webdriver/common/bidi/cdp.py",
    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", [])
