#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0

import os
import argparse


def touch(trigger):
    # If no trigger file is provided then do a return.
    if trigger is None:
        return

    if os.path.exists(trigger):
        os.utime(trigger, None)
    else:
        with open(trigger, 'w') as fp:
            fp.write("")


def main():
    parser = argparse.ArgumentParser(
        description='This script will walk the specified directory and write \
                     the file specified with the list of all sub-directories \
                     found. If to the output file already exists, the file \
                     will only be updated in case sub-directories has been \
                     added or removed since previous invocation.')

    parser.add_argument('-d', '--directory', required=True,
                        help='Directory to walk for sub-directory discovery')
    parser.add_argument('-c', '--create-links', required=False,
                        help='Create links for each directory found in \
                              directory given')
    parser.add_argument('-o', '--out-file', required=True,
                        help='File to write containing a list of all \
                              directories found')
    parser.add_argument('-t', '--trigger-file', required=False,
                        help='Trigger file to be be touched to re-run CMake')

    args = parser.parse_args()

    dirlist = []
    if args.create_links is not None:
        if not os.path.exists(args.create_links):
            os.makedirs(args.create_links)
        directory = args.directory
        symbase = os.path.basename(directory)
        symlink = args.create_links + os.path.sep + symbase
        if not os.path.exists(symlink):
            os.symlink(directory, symlink)
        dirlist.extend(symlink)
    else:
        dirlist.extend(args.directory)
    dirlist.extend(os.linesep)
    for root, dirs, _ in os.walk(args.directory, topdown=True):
        dirs.sort()
        for subdir in dirs:
            if args.create_links is not None:
                targetdirectory = os.path.join(root, subdir)
                reldir = os.path.relpath(targetdirectory, directory)
                linkname = symbase + '_' + reldir.replace(os.path.sep, '_')
                symlink = args.create_links + os.path.sep + linkname
                if not os.path.exists(symlink):
                    os.symlink(targetdirectory, symlink)
                dirlist.extend(symlink)
            else:
                dirlist.extend(os.path.join(root, subdir))
            dirlist.extend(os.linesep)

    new = ''.join(dirlist)
    existing = ''

    if os.path.exists(args.out_file):
        with open(args.out_file, 'r', encoding="utf-8") as fp:
            existing = fp.read()

        if new != existing:
            with open(args.out_file, 'w', encoding="utf-8") as fp:
                fp.write(new)
    else:
        with open(args.out_file, 'w', encoding="utf-8") as fp:
            fp.write(new)

    # Always touch trigger file to ensure json files are updated
    touch(args.trigger_file)


if __name__ == "__main__":
    main()
