#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF 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.

import os
import pathlib
from unittest import TestCase

from termcolor import colored

EXCLUDED_EXTENSIONS = ['.gif', '.png', '.pyc', 'LICENSE', 'DISCLAIMER', 'DISCLAIMER-WIP', 'NOTICE', '.whl']
EXCLUDED_DIRS = [
    'docs/build',
    'build',
    'dist',
    '.git',
    '.idea',
    'venv',
    '.venv',
    'apache_liminal.egg-info',
    '.pytest_cache',
]
EXCLUDED_FILES = ['DISCLAIMER-WIP', 'LICENSE.txt', '.autovenv', 'credentials-aws.txt']

PYTHON_LICENSE_HEADER = """
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF 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.
""".strip().split(
    "\n"
)

MD_LICENSE_HEADER = """
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF 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.
-->
""".strip().split(
    "\n"
)

RST_LICENSE_HEADER = """
..
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF 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.
..
""".strip().split(
    "\n"
)

BAT_LICENSE_HEADER = """
REM
REM Licensed to the Apache Software Foundation (ASF) under one
REM or more contributor license agreements.  See the NOTICE file
REM distributed with this work for additional information
REM regarding copyright ownership.  The ASF licenses this file
REM to you under the Apache License, Version 2.0 (the
REM "License"); you may not use this file except in compliance
REM with the License.  You may obtain a copy of the License at
REM
REM   http://www.apache.org/licenses/LICENSE-2.0
REM
REM Unless required by applicable law or agreed to in writing,
REM software distributed under the License is distributed on an
REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
REM KIND, either express or implied.  See the License for the
REM specific language governing permissions and limitations
REM under the License.
""".strip().split(
    "\n"
)

JSON_LICENSE_HEADER = """
  "": [
    "Licensed to the Apache Software Foundation (ASF) under one",
    "or more contributor license agreements.  See the NOTICE file",
    "distributed with this work for additional information",
    "regarding copyright ownership.  The ASF 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."
  ],
""".strip().split(
    "\n"
)


class TestLicenses(TestCase):
    def test_licenses(self):
        files = []
        base_dir = os.path.join(pathlib.Path(__file__).parent.parent.absolute())
        print(f'Checking licenses for files in {base_dir}')
        for r, d, f in os.walk(base_dir):
            if not any(os.path.relpath(r, base_dir).startswith(excluded) for excluded in EXCLUDED_DIRS):
                for file in f:
                    if (
                        not any(os.path.basename(file).endswith(ext) for ext in EXCLUDED_EXTENSIONS)
                        and not os.path.basename(file) in EXCLUDED_FILES
                    ):
                        files.append(os.path.join(r, file))

        output = ''
        files_missing_license = []
        success = True
        for file in files:
            print(f'Checking license for file {file}')
            has_license = self.check_license(file)
            if not has_license:
                output += colored(f'Missing License: {file}\n', 'red')
                files_missing_license.append(file)
            success = success and has_license

        print(output)

        if not success:
            self.assertListEqual([], files_missing_license)

    @staticmethod
    def check_license(file):
        header_lines = PYTHON_LICENSE_HEADER
        if file.endswith('.md'):
            header_lines = MD_LICENSE_HEADER
        elif file.endswith('.rst'):
            header_lines = RST_LICENSE_HEADER
        elif file.endswith('.bat'):
            header_lines = BAT_LICENSE_HEADER
        elif file.endswith('.json'):
            header_lines = JSON_LICENSE_HEADER
            header_lines[0] = f'  {header_lines[0]}'
        with open(file) as f:
            file_lines = f.readlines()
        return all(f'{line}\n' in file_lines for line in header_lines)
