#! /usr/bin/env python
#
# SCons - a Software Constructor
#
# Copyright (c) 2001 - 2019 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

'''Show or convert the configuration of an SCons cache directory.

A cache of derived files is stored by file signature.
The files are split into directories named by the first few
digits of the signature. The prefix length used for directory
names can be changed by this script.
'''

from __future__ import print_function
import argparse
import glob
import json
import os

__revision__ = "src/script/scons-configure-cache.py bee7caf9defd6e108fc2998a2520ddb36a967691 2019-12-17 02:07:09 bdeegan"

__version__ = "3.1.2"

__build__ = "bee7caf9defd6e108fc2998a2520ddb36a967691"

__buildsys__ = "octodog"

__date__ = "2019-12-17 02:07:09"

__developer__ = "bdeegan"


def rearrange_cache_entries(current_prefix_len, new_prefix_len):
    '''Move cache files if prefix length changed.

    Move the existing cache files to new directories of the
    appropriate name length and clean up the old directories.
    '''
    print('Changing prefix length from', current_prefix_len,
          'to', new_prefix_len)
    dirs = set()
    old_dirs = set()
    for file in glob.iglob(os.path.join('*', '*')):
        name = os.path.basename(file)
        dname = name[:current_prefix_len].upper()
        if dname not in old_dirs:
            print('Migrating', dname)
            old_dirs.add(dname)
        dname = name[:new_prefix_len].upper()
        if dname not in dirs:
            os.mkdir(dname)
            dirs.add(dname)
        os.rename(file, os.path.join(dname, name))

    # Now delete the original directories
    for dname in old_dirs:
        os.rmdir(dname)


# The configuration dictionary should have one entry per entry in the
# cache config. The value of each entry should include the following:
#   implicit - (optional) This is to allow adding a new config entry and also
#              changing the behaviour of the system at the same time. This
#              indicates the value the config entry would have had if it had
#              been specified.
#   default - The value the config entry should have if it wasn't previously
#             specified
#   command-line - parameters to pass to ArgumentParser.add_argument
#   converter - (optional) Function to call if conversion is required
#               if this configuration entry changes
config_entries = {
    'prefix_len': {
        'implicit': 1,
        'default': 2,
        'command-line': {
            'help': 'Length of cache file name used as subdirectory prefix',
            'metavar': '<number>',
            'type': int
        },
        'converter': rearrange_cache_entries
    }
}

parser = argparse.ArgumentParser(
    description='Modify the configuration of an scons cache directory',
    epilog='''
           Unspecified options will not be changed unless they are not
           set at all, in which case they are set to an appropriate default.
           ''')

parser.add_argument('cache-dir', help='Path to scons cache directory')
for param in config_entries:
    parser.add_argument('--' + param.replace('_', '-'),
                        **config_entries[param]['command-line'])
parser.add_argument('--version',
                    action='version',
                    version='%(prog)s 1.0')
parser.add_argument('--show',
                    action="store_true",
                    help="show current configuration")

# Get the command line as a dict without any of the unspecified entries.
args = dict([x for x in vars(parser.parse_args()).items() if x[1]])

# It seems somewhat strange to me, but positional arguments don't get the -
# in the name changed to _, whereas optional arguments do...
cache = args['cache-dir']
if not os.path.isdir(cache):
    raise RuntimeError("There is no cache directory named %s" % cache)
os.chdir(cache)
del args['cache-dir']

if not os.path.exists('config'):
    # old config dirs did not have a 'config' file. Try to update.
    # Validate the only files in the directory are directories 0-9, a-f
    expected = ['{:X}'.format(x) for x in range(0, 16)]
    if not set(os.listdir('.')).issubset(expected):
        raise RuntimeError(
            "%s does not look like a valid version 1 cache directory" % cache)
    config = dict()
else:
    with open('config') as conf:
        config = json.load(conf)

if args.get('show', None):
    print("Current configuration in '%s':" % cache)
    print(json.dumps(config, sort_keys=True,
                     indent=4, separators=(',', ': ')))
    # in case of the show argument, emit some stats as well
    file_count = 0
    for _, _, files in os.walk('.'):
        file_count += len(files)
    if file_count:  # skip config file if it exists
        file_count -= 1
    print("Cache contains %s files" % file_count)
    del args['show']

# Find any keys that are not currently set but should be
for key in config_entries:
    if key not in config:
        if 'implicit' in config_entries[key]:
            config[key] = config_entries[key]['implicit']
        else:
            config[key] = config_entries[key]['default']
        if key not in args:
            args[key] = config_entries[key]['default']

# Now go through each entry in args to see if it changes an existing config
# setting.
for key in args:
    if args[key] != config[key]:
        if 'converter' in config_entries[key]:
            config_entries[key]['converter'](config[key], args[key])
        config[key] = args[key]

# and write the updated config file
with open('config', 'w') as conf:
    json.dump(config, conf)
