#!/usr/bin/ruby
#
# General purpose C++ code generation.
#
require 'amqpgen'
require 'set'

Copyright=<<EOS
/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

///
/// This file was automatically generated from the AMQP specification.
/// Do not edit.
///


EOS

CppKeywords = Set.new(["and", "and_eq", "asm", "auto", "bitand",
                       "bitor", "bool", "break", "case", "catch", "char",
                       "class", "compl", "const", "const_cast", "continue",
                       "default", "delete", "do", "DomainInfo", "double",
                       "dynamic_cast", "else", "enum", "explicit", "extern",
                       "false", "float", "for", "friend", "goto", "if",
                       "inline", "int", "long", "mutable", "namespace", "new",
                       "not", "not_eq", "operator", "or", "or_eq", "private",
                       "protected", "public", "register", "reinterpret_cast",
                       "return", "short", "signed", "sizeof", "static",
                       "static_cast", "struct", "switch", "template", "this",
                       "throw", "true", "try", "typedef", "typeid",
                       "typename", "union", "unsigned", "using", "virtual",
                       "void", "volatile", "wchar_t", "while", "xor",
                       "xor_eq"])
# Names that need a trailing "_" to avoid clashes.
CppMangle = CppKeywords+Set.new(["std::string"])

class String
  def cppsafe() CppMangle.include?(self) ? self+"_" : self; end

  def amqp2cpp()
    path=split(".")
    name=path.pop
    return name.typename if path.empty?
    path.map! { |n| n.nsname }
    return (path << name.caps.cppsafe).join("::")
  end

  def typename() caps.cppsafe; end
  def nsname() bars.cppsafe; end
  def constname() shout.cppsafe; end
  def funcname() lcaps.cppsafe; end
  def varname() lcaps.cppsafe; end
end

# preview: Hold information about a C++ type.
# 
# new mapping does not use CppType,
# Each amqp type corresponds exactly by dotted name
# to a type, domain or struct, which in turns
# corresponds by name to a C++ type or typedef.
# (see String.amqp2cpp)
# 
class CppType
  def initialize(name) @name=@param=@ret=name; end
  attr_reader :name, :param, :ret, :code
  
  def retref() @ret="#{name}&"; self; end
  def retcref() @ret="const #{name}&"; self; end
  def passcref() @param="const #{name}&"; self; end
  def code(str) @code=str; self; end
  def defval(str) @defval=str; self; end
  def encoded() @code end
  def ret_by_val() @name; end

  def encode(value, buffer)
    @code ? "#{buffer}.put#{@code}(#{value});" : "#{value}.encode(#{buffer});"
  end

  def decode(value,buffer)
    if @code
      if /&$/===param then
        "#{buffer}.get#{@code}(#{value});"
      else
        "#{value} = #{buffer}.get#{@code}();"
      end
    else
      "#{value}.decode(#{buffer});"
    end
  end

  def default_value()
    return @defval ||= "#{name}()"
  end

  def to_s() name; end;
end

class AmqpRoot
  # preview; map 0-10 types to preview code generator types
  @@typemap = {
    "bit"=> CppType.new("bool").code("Octet").defval("false"),
    "boolean"=> CppType.new("bool").code("Octet").defval("false"),
    "uint8"=>CppType.new("uint8_t").code("Octet").defval("0"), 
    "uint16"=>CppType.new("uint16_t").code("Short").defval("0"),
    "uint32"=>CppType.new("uint32_t").code("Long").defval("0"),
    "uint64"=>CppType.new("uint64_t").code("LongLong").defval("0"),
    "datetime"=>CppType.new("uint64_t").code("LongLong").defval("0"),
    "str8"=>CppType.new("std::string").passcref.retcref.code("ShortString"),
    "str16"=>CppType.new("std::string").passcref.retcref.code("MediumString"),
    "str32"=>CppType.new("std::string").passcref.retcref.code("LongString"),
    "vbin8"=>CppType.new("std::string").passcref.retcref.code("ShortString"),
    "vbin16"=>CppType.new("std::string").passcref.retcref.code("MediumString"),
    "vbin32"=>CppType.new("std::string").passcref.retcref.code("LongString"),
    "map"=>CppType.new("FieldTable").passcref.retcref,
    "array"=>CppType.new("Array").passcref.retcref,
    "sequence-no"=>CppType.new("SequenceNumber").passcref,
    "sequence-set"=>CppType.new("SequenceSet").passcref.retcref,
    "struct32"=>CppType.new("std::string").passcref.retcref.code("LongString"),
    "uuid"=>CppType.new("Uuid").passcref.retcref,
    "byte-ranges"=>CppType.new("ByteRanges").passcref.retcref
  }

  # preview: map amqp types to preview cpp types.
  def lookup_cpptype(t) t = @@typemap[t] and return t end
end


class AmqpElement
  # convert my amqp type_ attribute to a C++ type.
  def amqp2cpp()
    return "ArrayDomain<#{array_type(name).amqp2cpp}> " if type_=="array"
    return type_.amqp2cpp
  end

  # Does this object have a type-like child named name?
  def typechild(name)
    child = domain(name) if respond_to? :domain
    child = struct(name) if not child and respond_to? :struct
    child = type_(name) if not child and respond_to? :type_
    child
  end

  # dotted name to a type object
  def dotted_typechild(name)
    names=name.split('.')
    context = self
    while context and names.size > 1
      context = context.child_named(names.shift) 
    end
    return context.typechild(names[0]) if context
  end
  
  # preview mapping - type_ attribute to C++ type
  def lookup_cpptype(name)
    if t = root.lookup_cpptype(name) then return t 
    elsif c = containing_class.typechild(name) then return c.cpptype
    elsif c= root.dotted_typechild(name) then return c.cpptype
    else raise "Cannot resolve type-name #{name} from #{self}" 
    end
  end
  
  def containing_class()
    return self if is_a? AmqpClass
    return parent && parent.containing_class
  end
end


class AmqpField
  def struct?() 
    c=containing_class
    c.struct(type_)
  end
  def cpptype() lookup_cpptype(type_)  or raise "no cpptype #{type_} for field #{self}" end
  def cppname() name.lcaps.cppsafe; end
  def bit?() type_ == "bit"; end
  def signature() cpptype.param+" "+cppname; end

  def fqtypename()
    unless type_.index(".") 
      c=containing_class
      return c.domain(type_).fqtypename if c.domain(type_)
      return c.struct(type_).fqclassname if c.struct(type_)
    end
    return amqp2cpp
  end
  def paramtype()
    /^(int|uint|char|boolean|bit)/ === type_ ? fqtypename : "const #{fqtypename}&"
  end
  def param_default() "=#{fqtypename}()"  end

  # Default value is normally the C++ default but over-ridden in specific cases
  def default_value()
    defval = cpptype.default_value;
    if name == "accept-mode" and parent.name == "transfer" then defval = "1";  end
    return defval
  end
end

class AmqpMethod
  def cppname() name.lcaps.cppsafe; end
  def param_names() fields.map { |f| f.cppname }; end
  def signature() fields.map { |f| f.signature }; end
  def classname() parent.name; end
  def body_name() 
    classname().caps+name.caps+"Body"      
  end
  def cpp_pack_type() root.lookup_cpptype("uint16") end
end

module AmqpHasFields
  def parameters(with_default=nil)
    fields.map { |f|
      "#{f.paramtype} #{f.cppname}_#{f.param_default if with_default}"
    }
  end
  def unused_parameters() fields.map { |f| "#{f.paramtype} /*#{f.cppname}_*/"} end
  def arguments() fields.map { |f| "#{f.cppname}_"} end
  def values() fields.map { |f| "#{f.cppname}"} end
  def initializers() fields.map { |f| "#{f.cppname}(#{f.cppname}_)"}  end
end

class AmqpAction
  def classname() name.typename; end
  def funcname() parent.name.funcname + name.caps; end
  def fqclassname() parent.name+"::"+classname; end
  def full_code() (containing_class.code.hex << 8)+code.hex; end
  include AmqpHasFields
end

class AmqpType
  def cpptype() root.lookup_cpptype(name) end # preview
  def typename() name.typename; end      # new mapping
  def fixed?() fixed_width; end
end

class AmqpCommand < AmqpAction
  def base() "Command";  end
end

class AmqpControl < AmqpAction
  def base() "Control";  end
end

class AmqpClass
  def cppname() name.caps; end  # preview
  def nsname() name.nsname; end
end

class AmqpDomain
  # preview
  def cpptype() lookup_cpptype(type_) end
  def cppname() name.caps; end

  # new mapping
  def fqtypename()
    return containing_class.nsname+"::"+name.typename if containing_class
    name.typename
  end
end

class AmqpResult
  # preview
  def cpptype()
    if type_ then lookup_cpptype(type_)
    else CppType.new(parent.parent.name.caps+parent.name.caps+"Result").passcref
    end
  end
end

class AmqpStruct
  include AmqpHasFields

  @@pack_types={ "1"=>"uint8", "2"=>"uint16", "4"=>"uint32"}
  def cpp_pack_type()           # preview
    root.lookup_cpptype(@@pack_types[pack])
  end 
  def cpptype() CppType.new(cppname).passcref.retcref end
  #def cppname() containing_class.cppname+name.caps;  end
  def cppname()
    if parent.kind_of? AmqpResult
      parent.parent.parent.name.caps+parent.parent.name.caps+"Result"
    else
      name.caps  
    end
  end
  def fqclassname() containing_class.nsname+"::"+name.typename;  end
  def classname() name.typename; end
  def full_code() (containing_class.code.hex << 8)+code.hex; end
end

class CppGen < Generator
  def initialize(outdir, *specs)
    super(outdir,*specs)
    # need to sort classes for dependencies
    @actions=[]                 # Stack of end-scope actions
  end

  # Write a header file. 
  def h_file(path, &block)
    path = (/\.h$/ === path ? path : path+".h")
    guard=path.upcase.tr('./-','_')
    file(path) { 
      gen "#ifndef #{guard}\n"
      gen "#define #{guard}\n"
      gen Copyright
      yield
      gen "#endif  /*!#{guard}*/\n" 
    }
  end

  # Write a .cpp file.
  def cpp_file(path, &block)
    path = (/\.cpp$/ === path ? path : path+".cpp")
    file(path) do
      gen Copyright
      yield
    end
  end

  def include(header)
    header+=".h" unless /(\.h|[">])$/===header
    header="\"#{header}\"" unless /(^<.*>$)|(^".*"$)/===header
    genl "#include #{header}"
  end

  def scope(open="{",close="}", &block)
    genl open
    indent &block
    genl close
  end
  
  def namespace(name, &block) 
    genl
    names = name.split("::")
    names.each { |n| genl "namespace #{n} {" }
    genl "namespace {" if (names.empty?)
    genl
    yield
    genl
    genl('}'*([names.size, 1].max)+" // namespace "+name)
    genl
  end

  def struct_class(type, name, bases, &block)
    gen "#{type} #{name}"
    if (!bases.empty?)
      genl ":"
      indent { gen "#{bases.join(",\n")}" }
    end
    genl
    scope("{","};", &block)
  end

  def struct(name, *bases, &block)
    struct_class("struct", name, bases, &block);
  end
  def cpp_class(name, *bases, &block)
    struct_class("class", name, bases, &block);
  end
  def cpp_extern_class(scope, name, *bases, &block)
    struct_class("class "+scope, name, bases, &block);
  end

  def typedef(type, name) genl "typedef #{type} #{name};\n"; end

  def variant(types) "boost::variant<#{types.join(", ")}>"; end
  def variantl(types) "boost::variant<#{types.join(", \n")}>"; end
  def blank_variant(types) variant(["boost::blank"]+types); end
  def tuple(types) "boost::tuple<#{types.join(', ')}>"; end

  def public() outdent { genl "public:" } end
  def private() outdent { genl "private:" } end
  def protected() outdent { genl "protected:" } end

  # Returns [namespace, classname, filename]
  def parse_classname(full_cname)
    names=full_cname.split("::")
    return names[0..-2].join('::'), names[-1], names.join("/") 
  end

  def doxygen_comment(&block)
    genl "/**"
    prefix(" * ",&block)
    genl " */"
  end

  # Generate code in namespace for each class
  def each_class_ns()
    @amqp.classes.each { |c| namespace(c.nsname) { yield c } }
  end

  def signature(ret_name, params, trailer="")
    if params.size <= 1
      genl ret_name+"(#{params})"+trailer
    else
      scope(ret_name+"(",")"+trailer) { genl params.join(",\n") }
    end
  end
  
  def function_decl(ret_name, params=[], trailer="")
    signature(ret_name, params, trailer+";")
  end

  def function_defn(ret_name, params=[], trailer="")
    genl
    signature(ret_name, params, trailer)
    scope() { yield }
  end

  def ctor_decl(name, params=[]) function_decl(name, params); end
  
  def ctor_defn(name, params=[], inits=[])
    signature(name, params, inits.empty? ? "" : " :")
    indent { gen inits.join(",\n") } if not inits.empty?
    scope() { yield }
  end

  def function_call(name, params=[], trailer="")
    gen name
    list "(",params, ")"
    gen trailer
  end
end

# Fully-qualified class name
class FqClass < Struct.new(:fqname,:namespace,:name,:file)
  def initialize(fqclass)
    names=fqclass.split "::"
    super(fqclass, names[0..-2].join('::'), names[-1], names.join("/"))
  end
end

