# Copyright (C) 2018-2019 Apple Inc. All rights reserved.
#
# 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.

require_relative 'Fits'

class Metadata
    @@emitter_local = nil

    def initialize(fields, initializers)
        @fields = fields
        @initializers = initializers
    end

    def empty?
        @fields.nil?
    end

    def length
        empty? ? 0 : @fields.length
    end

    def struct(op)
        return if empty?

        def generateOffsetOfFunctions(prefix, fieldNames)
            fieldNames.map do |fieldName|
                "#{prefix}static ptrdiff_t offsetOf#{fieldName[0].upcase}#{fieldName[1..-1]}() { return OBJECT_OFFSETOF(Metadata, m_#{fieldName}); }"
            end.join("\n")
        end

        def convertFields(prefix, fields, fieldNames)
            fields.map do |field, type|
                if type.kind_of? Hash
                    "#{prefix}union {\n#{convertFields(prefix + '    ', type, fieldNames)}\n#{prefix}};"
                else
                    fieldName = field.to_s
                    fieldNames.push(fieldName)
                    "#{prefix}#{type.to_s} m_#{fieldName};"
                end
            end.join("\n")
        end

        fieldNames = []
        prefix = "        "
        fields = convertFields(prefix, @fields, fieldNames)
        fields = fields + "\n" + generateOffsetOfFunctions(prefix, fieldNames)

        inits = nil
        if @initializers && (not @initializers.empty?)
            inits = "\n            : " + @initializers.map do |metadata, arg|
                "m_#{metadata}(__op.m_#{arg})"
            end.join("\n            , ").concat("\n       ");
        end

        <<-EOF

    struct Metadata {
        WTF_MAKE_NONCOPYABLE(Metadata);

    public:
        #{op.opcodeID}
        Metadata(const #{op.capitalized_name}&#{" __op" if inits})#{inits} { }

#{fields}
    };
EOF
    end

    def accessor
        return if empty?

        <<-EOF

    Metadata& metadata(CodeBlock* codeBlock) const
    {
        return codeBlock->metadata<Metadata>(opcodeID, #{Metadata.field_name});
    }
EOF
    end

    def field(prefix)
        return if empty?

        "\n#{prefix}unsigned #{Metadata.field_name};"
    end

    def load_from_stream(index, size)
        return if empty?

        "#{Metadata.field_name}(#{Fits::convert(size, "stream[#{index}]", :unsigned)})"
    end

    def create_emitter_local
        return if empty?

        <<-EOF.chomp

        auto #{emitter_local.name} = gen->addMetadataFor(opcodeID);
        EOF
    end

    def emitter_local_name
        "__metadataID"
    end

    def emitter_local
        unless @@emitter_local
            @@emitter_local = Argument.new(emitter_local_name, :unsigned, -1)
        end

        return @@emitter_local
    end

    def self.field_name
        "m_metadataID"
    end
end
