module Lutaml::Model::Type

def self.cast(value, type)

def self.cast(value, type)
  return if value.nil?
  case type.to_s.split("::").last
  when "String"
    value.to_s
  when "Integer"
    value.to_i
  when "Float"
    value.to_f
  when "Date"
    begin
      ::Date.parse(value.to_s)
    rescue ArgumentError
      nil
    end
  when "DateTime"
    DateTime.cast(value)
  when "Time"
    ::Time.parse(value.to_s)
  when "TimeWithoutDate"
    TimeWithoutDate.cast(value)
  when "Boolean"
    to_boolean(value)
  when "Decimal"
    BigDecimal(value.to_s)
  when "Hash"
    normalize_hash(Hash(value))
  when "Uuid"
    UUID_REGEX.match?(value) ? value : SecureRandom.uuid
  when "Symbol"
    value.to_sym
  when "Binary"
    value.force_encoding("BINARY")
  when "Url"
    URI.parse(value.to_s)
  when "IpAddress"
    IPAddr.new(value.to_s)
  when "Json"
    Json.cast(value)
  else
    value
  end
end

def self.normalize_hash(hash)

def self.normalize_hash(hash)
  return hash["text"] if hash.keys == ["text"]
  hash.filter_map do |key, value|
    next if key == "text"
    if value.is_a?(::Hash)
      [key, normalize_hash(value)]
    else
      [key, value]
    end
  end.to_h
end

def self.serialize(value, type)

def self.serialize(value, type)
  return if value.nil?
  case type.to_s.split("::").last
  when "Date"
    value.iso8601
  when "DateTime"
    DateTime.serialize(value)
  when "Integer"
    value.to_i
  when "Float"
    value.to_f
  when "Boolean"
    to_boolean(value)
  when "Decimal"
    value.to_s("F")
  when "Hash"
    Hash(value)
  when "Json"
    value.to_json
  else
    value.to_s
  end
end

def self.to_boolean(value)

def self.to_boolean(value)
  if value == true || value.to_s =~ (/^(true|t|yes|y|1)$/i)
    return true
  end
  if value == false || value.nil? || value.to_s =~ (/^(false|f|no|n|0)$/i)
    return false
  end
  raise ArgumentError.new("invalid value for Boolean: \"#{value}\"")
end