#!/usr/bin/env python3
# Copyright 2022 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import json, os, sys
from collections import namedtuple

from generator_lib import Generator, run_generator, FileRender, GeneratorOutput


def parse_mask(mask):
    if mask:
        return int(mask, 0)
    return 0xffffffff


class Name:
    def __init__(self, name):
        self.name = name
        self.chunks = name.split(' ')

    def get(self):
        return self.name

    def CamelChunk(self, chunk):
        return chunk[0].upper() + chunk[1:]

    def canonical_case(self):
        return (' '.join(self.chunks)).lower()

    def concatcase(self):
        return ''.join(self.chunks)

    def camelCase(self):
        return self.chunks[0] + ''.join(
            [self.CamelChunk(chunk) for chunk in self.chunks[1:]])

    def CamelCase(self):
        return ''.join([self.CamelChunk(chunk) for chunk in self.chunks])

    def SNAKE_CASE(self):
        return '_'.join([chunk.upper() for chunk in self.chunks])

    def snake_case(self):
        return '_'.join(self.chunks)

    def js_enum_case(self):
        result = self.chunks[0].lower()
        for chunk in self.chunks[1:]:
            if not result[-1].isdigit():
                result += '-'
            result += chunk.lower()
        return result


class Architecture:
    def __init__(self, name, json_data, mask):
        self.name = Name(name)
        self.devices = []

        mask_num = parse_mask(mask)

        for device in json_data:
            device_num = int(device, 0)

            # Don't allow duplicate entries
            assert device not in self.devices, 'Architecture "{}" contained duplicate deviceID "{}"'.format(
                self.name.get(), device)
            # Ensure that all device IDs don't contain bits outside the mask
            assert device_num & mask_num == device_num, 'Architecture "{}" contained deviceID "{}" which doesn\'t match the given mask of "{}"'.format(
                self.name.get(), device, mask)

            self.devices.append(device)


class DeviceSet:
    def __init__(self, json_data):
        self.mask = None
        self.internal = False

        if 'mask' in json_data:
            self.mask = json_data['mask']

        if 'internal' in json_data:
            self.internal = json_data['internal']

        self.architectures = []
        if 'architecture' in json_data:
            for (arch_name, arch_data) in json_data['architecture'].items():
                # Skip any entries that start with an underscore. Used for comments.
                if arch_name[0] == '_':
                    continue

                architecture = Architecture(arch_name, arch_data, self.mask)

                # Validate that deviceIDs are only allowed to be in one Architecture at a time
                for other_architecture in self.architectures:
                    for device in architecture.devices:
                        assert device not in other_architecture.devices, 'Architectures "{}" and "{}" both contain deviceID "{}"'.format(
                            architecture.name.get(),
                            other_architecture.name.get(), device)

                self.architectures.append(architecture)

    def validate_devices(self, other_devices, other_mask):
        combined_mask = parse_mask(self.mask) & parse_mask(other_mask)

        for other_device in other_devices:
            other_device_num = int(other_device, 0) & combined_mask
            for architecture in self.architectures:
                for device in architecture.devices:
                    device_num = int(device, 0) & combined_mask
                    assert device_num != other_device_num, 'DeviceID "{}" & mask "{}" conflicts with deviceId "{}" & mask "{}" in architecture "{}"'.format(
                        other_device, other_mask, device, self.mask,
                        architecture.name.get())

    def maskDeviceId(self):
        if not self.mask:
            return ''
        return ' & ' + self.mask


class Vendor:
    def __init__(self, name, json_data):
        self.name = Name(name)
        self.id = json_data['id']

        architecture_dict = {}
        internal_architecture_dict = {}

        self.device_sets = []
        if 'devices' in json_data:
            for device_data in json_data['devices']:
                device_set = DeviceSet(device_data)

                for architecture in device_set.architectures:

                    # Validate that deviceIDs are unique across device sets
                    for other_device_set in self.device_sets:
                        # Only validate device IDs between internal and public device sets.
                        if other_device_set.internal == device_set.internal:
                            assert device_set.mask != other_device_set.mask, 'Vendor "{}" contained duplicate device masks "{}"'.format(
                                self.name.get(), device_set.mask)
                            other_device_set.validate_devices(
                                architecture.devices, device_set.mask)

                        # Validate that architecture names are unique between internal and public device sets.
                        else:
                            for other_architecture in other_device_set.architectures:
                                assert architecture.name.canonical_case(
                                ) != other_architecture.name.canonical_case(
                                ), '"{}" is defined as both an internal and public architecture'.format(
                                    architecture.name.get())

                    if device_set.internal:
                        internal_architecture_dict[
                            architecture.name.canonical_case(
                            )] = architecture.name
                    else:
                        architecture_dict[architecture.name.canonical_case(
                        )] = architecture.name

                self.device_sets.append(device_set)

        # List of unique architecture names under this vendor
        self.architecture_names = architecture_dict.values()
        self.internal_architecture_names = internal_architecture_dict.values()


def parse_json(json):
    vendors = []
    internal_architecture_count = 0

    for (vendor_name, vendor_data) in json['vendors'].items():
        # Skip vendors that have a leading underscore. Those are intended to be "comments".
        if vendor_name[0] == '_':
            continue

        vendor = Vendor(vendor_name, vendor_data)
        vendors.append(vendor)
        internal_architecture_count += len(vendor.internal_architecture_names)

    return {
        'vendors': vendors,
        'has_internal': internal_architecture_count > 0
    }


class DawnGpuInfoGenerator(Generator):
    def get_description(self):
        return "Generates GPU Info Dawn code."

    def add_commandline_arguments(self, parser):
        parser.add_argument('--gpu-info-json',
                            required=True,
                            type=str,
                            help='The GPU Info JSON definition to use.')

    def get_dependencies(self, args):
        return [os.path.abspath(args.gpu_info_json)]

    def get_outputs(self, args):
        with open(args.gpu_info_json) as f:
            loaded_json = json.loads(f.read())

        params = parse_json(loaded_json)

        renders = [
            FileRender("dawn/common/GPUInfo.h",
                       "src/dawn/common/GPUInfo_autogen.h", [params]),
            FileRender("dawn/common/GPUInfo.cpp",
                       "src/dawn/common/GPUInfo_autogen.cpp", [params]),
        ]
        return GeneratorOutput(renders=renders, imported_templates=[])


if __name__ == "__main__":
    sys.exit(run_generator(DawnGpuInfoGenerator()))
