import json
import sys


def main():
    filepath = sys.argv[1]
    with open(filepath, 'r') as f:
        config_json = json.load(f)

    for req_key, req_type in (
            ('context_length', int),
            ('timeout', float),
            ('memory_allocated', str),
            ('sharding', bool),
            ('max_messages', int),
    ):
        if req_key not in config_json:
            print(f'Config does not contain {req_key}.')
            sys.exit(1)
        try:
            config_json[req_key] = req_type(config_json[req_key])
        except ValueError:
            print(f'{req_key} entry ({config_json[req_key]}) is not correct type.')
            sys.exit(1)

    context_length = config_json['context_length']
    timeout = config_json['timeout']
    memory_allocated = config_json['memory_allocated']
    sharding = config_json['sharding']
    max_messages = config_json['max_messages']

    if not memory_allocated.endswith('G'):
        print('Memory allocation needs to be provided in Gigabyte (G).')
        sys.exit(1)
    memory_allocated = int(memory_allocated[:-1])

    # Check max_messages and set minimum requirements
    if max_messages <= 10:
        min_context_length = 512
        min_timeout = 1
        min_memory = 128
        sharding_required = False
    elif max_messages <= 15:
        min_context_length = 1024
        min_timeout = 2
        min_memory = 512
        sharding_required = False
    elif max_messages <= 20:
        min_context_length = 2048
        min_timeout = 10
        min_memory = 2048
        sharding_required = True
    elif max_messages <= 40:
        min_context_length = 4096
        min_timeout = 20
        min_memory = 4096
        sharding_required = True
    else:
        print('Max messages too high (<= 40).')
        sys.exit(1)

    found_problem = False

    # Validate other parameters based on max_messages requirements
    if context_length < min_context_length:
        print(f'Context length too small. Minimum required: {min_context_length}')
        found_problem = True

    if timeout < min_timeout:
        print(f'Timeout too small. Minimum required: {min_timeout}')
        found_problem = True

    if memory_allocated < min_memory:
        print(f'Memory allocation too small. Minimum required: {min_memory}G')
        found_problem = True

    if sharding_required and not sharding:
        print('Sharding is required.')
        found_problem = True
    elif not sharding_required and sharding:
        print('Sharding is not supported for this configuration.')
        found_problem = True

    if not found_problem:
        print('Config is valid.')
    else:
        sys.exit(1)


if __name__ == '__main__':
    main()
