#!/usr/bin/env python3
#
# Copyright (c) 2022 Project CHIP Authors
#
# Licensed 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 argparse
from collections import namedtuple
import configparser
import logging
import subprocess
import os

CHIP_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))

ALL_PLATFORMS = set([
    'ameba',
    'android',
    'bl602',
    'bouffalolab',
    'cc13x2_26x2',
    'cc32xx',
    'darwin',
    'efr32',
    'esp32',
    'infineon',
    'k32w0',
    'linux',
    'mbed',
    'nrfconnect',
    'qpg',
    'telink',
    'tizen',
    'webos',
    'mw320',
    'genio',
    'openiotsdk',
])

Module = namedtuple('Module', 'name path platforms')


def load_module_info() -> None:
    config = configparser.ConfigParser()
    config.read(os.path.join(CHIP_ROOT, '.gitmodules'))

    for name, module in config.items():
        if name != 'DEFAULT':
            platforms = module.get('platforms', '').split(',')
            platforms = set(filter(None, platforms))
            assert not (platforms - ALL_PLATFORMS), "Submodule's platform not contained in ALL_PLATFORMS"
            yield Module(name=name, path=module['path'], platforms=platforms)


def module_matches_platforms(module: Module, platforms: set) -> bool:
    # If no platforms have been selected, or the module is not associated with any specific
    # platforms, treat it as a match.
    if not platforms or not module.platforms:
        return True
    return bool(platforms & module.platforms)


def make_chip_root_safe_directory() -> None:
    # ensure no errors regarding ownership in the directory. Newer GIT seems to require this:
    subprocess.check_call(['git', 'config', '--global', '--add', 'safe.directory', CHIP_ROOT])


def checkout_modules(modules: list, shallow: bool, force: bool, recursive: bool) -> None:
    names = [module.name.replace('submodule "', '').replace('"', '') for module in modules]
    names = ', '.join(names)
    logging.info(f'Checking out: {names}')

    cmd = ['git', '-C', CHIP_ROOT, 'submodule', 'update', '--init']
    cmd += ['--depth', '1'] if shallow else []
    cmd += ['--force'] if force else []
    cmd += ['--recursive'] if recursive else []
    cmd += [module.path for module in modules]

    subprocess.check_call(cmd)


def deinit_modules(modules: list, force: bool) -> None:
    names = [module.name.replace('submodule "', '').replace('"', '') for module in modules]
    names = ', '.join(names)
    logging.info(f'Deinitializing: {names}')

    cmd = ['git', '-C', CHIP_ROOT, 'submodule', 'deinit']
    cmd += ['--force'] if force else []
    cmd += [module.path for module in modules]

    subprocess.check_call(cmd)


def main():
    logging.basicConfig(format='%(message)s', level=logging.INFO)

    parser = argparse.ArgumentParser(description='Checkout or update relevant git submodules')
    parser.add_argument('--shallow', action='store_true', help='Fetch submodules without history')
    parser.add_argument('--platform', nargs='+', choices=ALL_PLATFORMS, default=[],
                        help='Process submodules for specific platforms only')
    parser.add_argument('--force', action='store_true', help='Perform action despite of warnings')
    parser.add_argument('--deinit-unmatched', action='store_true',
                        help='Deinitialize submodules for non-matching platforms')
    parser.add_argument('--recursive', action='store_true', help='Recursive init of the listed submodules')
    args = parser.parse_args()

    modules = list(load_module_info())
    selected_platforms = set(args.platform)
    selected_modules = [m for m in modules if module_matches_platforms(m, selected_platforms)]
    unmatched_modules = [m for m in modules if not module_matches_platforms(m, selected_platforms)]

    make_chip_root_safe_directory()
    checkout_modules(selected_modules, args.shallow, args.force, args.recursive)

    if args.deinit_unmatched:
        deinit_modules(unmatched_modules, args.force)


if __name__ == '__main__':
    main()
