#
# Copyright (C) 2008-2010 Wayne Meissner
#
# This file is part of ruby-ffi.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
# * 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.
# * Neither the name of the Ruby FFI project 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 OWNER 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.
#

module FFI

  # Build a {StructLayout struct layout}.
  class StructLayoutBuilder
    attr_reader :size
    attr_reader :alignment

    def initialize
      @size = 0
      @alignment = 1
      @min_alignment = 1
      @packed = false
      @union = false
      @fields = Array.new
    end

    # Set size attribute with +size+ only if +size+ is greater than attribute value.
    # @param [Numeric] size
    def size=(size)
      @size = size if size > @size
    end

    # Set alignment attribute with +align+ only if it is greater than attribute value.
    # @param [Numeric] align
    def alignment=(align)
      @alignment = align if align > @alignment
      @min_alignment = align
    end

    # Set union attribute.
    # Set to +true+ to build a {Union} instead of a {Struct}.
    # @param [Boolean] is_union
    # @return [is_union]
    def union=(is_union)
      @union = is_union
    end

    # Building a {Union} or a {Struct} ?
    #
    # @return [Boolean]
    #
    def union?
      @union
    end

    # Set packed attribute
    # @overload packed=(packed) Set alignment and packed attributes to
    #   +packed+.
    #
    #   @param [Fixnum] packed
    #
    #   @return [packed]
    # @overload packed=(packed) Set packed attribute.
    #   @param packed
    #
    #   @return [0,1]
    #
    def packed=(packed)
      if packed.is_a?(0.class)
        @alignment = packed
        @packed = packed
      else
        @packed = packed ? 1 : 0
      end
    end


    # List of number types
    NUMBER_TYPES = [
      Type::INT8,
      Type::UINT8,
      Type::INT16,
      Type::UINT16,
      Type::INT32,
      Type::UINT32,
      Type::LONG,
      Type::ULONG,
      Type::INT64,
      Type::UINT64,
      Type::FLOAT32,
      Type::FLOAT64,
      Type::LONGDOUBLE,
      Type::BOOL,
    ]

    # @param [String, Symbol] name name of the field
    # @param [Array, DataConverter, Struct, StructLayout::Field, Symbol, Type] type type of the field
    # @param [Numeric, nil] offset
    # @return [self]
    # Add a field to the builder.
    # @note Setting +offset+ to +nil+ or +-1+ is equivalent to +0+.
    def add(name, type, offset = nil)

      if offset.nil? || offset == -1
        offset = @union ? 0 : align(@size, @packed ? [ @packed, type.alignment ].min : [ @min_alignment, type.alignment ].max)
      end

      #
      # If a FFI::Type type was passed in as the field arg, try and convert to a StructLayout::Field instance
      #
      field = type.is_a?(StructLayout::Field) ? type : field_for_type(name, offset, type)
      @fields << field
      @alignment = [ @alignment, field.alignment ].max unless @packed
      @size = [ @size, field.size + (@union ? 0 : field.offset) ].max

      return self
    end

    # @param (see #add)
    # @return (see #add)
    # Same as {#add}.
    # @see #add
    def add_field(name, type, offset = nil)
      add(name, type, offset)
    end

    # @param (see #add)
    # @return (see #add)
    # Add a struct as a field to the builder.
    def add_struct(name, type, offset = nil)
      add(name, Type::Struct.new(type), offset)
    end

    # @param name (see #add)
    # @param type (see #add)
    # @param [Numeric] count array length
    # @param offset (see #add)
    # @return (see #add)
    # Add an array as a field to the builder.
    def add_array(name, type, count, offset = nil)
      add(name, Type::Array.new(type, count), offset)
    end

    # @return [StructLayout]
    # Build and return the struct layout.
    def build
      # Add tail padding if the struct is not packed
      size = @packed ? @size : align(@size, @alignment)

      layout = StructLayout.new(@fields, size, @alignment)
      layout.__union! if @union
      layout
    end

    private

    # @param [Numeric] offset
    # @param [Numeric] align
    # @return [Numeric]
    def align(offset, align)
      align + ((offset - 1) & ~(align - 1));
    end

    # @param (see #add)
    # @return [StructLayout::Field]
    def field_for_type(name, offset, type)
      field_class = case
      when type.is_a?(Type::Function)
        StructLayout::Function

      when type.is_a?(Type::Struct)
        StructLayout::InnerStruct

      when type.is_a?(Type::Array)
        StructLayout::Array

      when type.is_a?(FFI::Enum)
        StructLayout::Enum

      when NUMBER_TYPES.include?(type)
        StructLayout::Number

      when type == Type::POINTER
        StructLayout::Pointer

      when type == Type::STRING
        StructLayout::String

      when type.is_a?(Class) && type < StructLayout::Field
        type

      when type.is_a?(DataConverter)
        return StructLayout::Mapped.new(name, offset, Type::Mapped.new(type), field_for_type(name, offset, type.native_type))

      when type.is_a?(Type::Mapped)
        return StructLayout::Mapped.new(name, offset, type, field_for_type(name, offset, type.native_type))

      else
        raise TypeError, "invalid struct field type #{type.inspect}"
      end

      field_class.new(name, offset, type)
    end
  end

end
