#!/usr/bin/env ruby
#
# 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.
#
require 'pathname'
require 'amqpgen'

#
# Run a set of code generation templates.
#
if ARGV.size < 3
  puts <<EOS
Usage: #{ARGV[0]} SRCDIR APIDIR SPEC.xml [ ... ] TEMPLATE.rb [ ... ]
or:    #{ARGV[0]} SRCDIR APIDIR SPEC.xml [ ... ] all [ makefragment.mk | makefragment.cmake ]

Parse all SPEC.xml files to create an AMQP model, run each TEMPLATE
putting the resulting files under SRCDIR, public API files in APIdir.
Prints a list of files generated to standard output.

If SRCDIR and APIDIR are '-'  then just prints file list without generating files.
EOS
  exit 1
end

# Create array of specs by version
def parse_specs(files)
  lists=Hash.new { |h,k| h[k]=[] }
  files.each { |f|
    spec=AmqpRoot.new(File.new(f))
    lists[spec.version] << spec
  }
  specs={}
  lists.each_pair { |k,l|
    specs[k] = l.size==1 ? l.first : AmqpRoot.new(*l.map { |s| s.xml})
  }
  return specs
end

gendir=File.dirname(__FILE__)

# Run selected templates
if ARGV.any? { |arg| arg=="all" }
  templates=Dir["#{gendir}/*/*.rb"]
else
templates=ARGV.grep(/\.rb$/)
  ARGV.each { |arg|
    d=File.join gendir,arg
    templates += Dir["#{d}/*.rb"] if File.directory? d
  }
end

$outdir=[ ARGV[0], ARGV[1] ]
$models=parse_specs(ARGV.grep(/\.xml$/))

templates.each { |t|
  ver=Pathname.new(t).dirname.basename.to_s.split('.')[-1]
  $amqp=$models[ver]
  if $amqp
    load t
  else
    puts "Warning: skipping #{t}, no spec file for version #{ver}."
  end
}

def cmake_continue(lines) lines.join(" \n    "); end
def make_continue(lines) lines.join(" \\\n    "); end

# Generate makefile
makefile=ARGV.grep(/.mk$/)[0]
cmakefile=ARGV.grep(/.cmake$/)[0]
if cmakefile || makefile
  srcdir,apidir=$outdir
  dir=Dir.getwd
  Dir.chdir File.dirname(__FILE__)
  generator_files=Dir["**/*.rb"] << File.basename(__FILE__)
  Dir.chdir dir
  rgen_generator=generator_files.map{ |f| "$(rgen_dir)/#{f}" }
  cmake_rgen_generator=generator_files.map{ |f| "${rgen_dir}/#{f}" }
  rgen_srcs=GenFiles.get.map{ |f| "#{GenFiles.public_api?(f) ? apidir : srcdir}/#{f}" }
  rgen_subdirs={}
  rgen_srcs.each { |src|
    if src.match(%r{(#{srcdir}|#{apidir})/qpid/([^/]+)/})
      subdir=$2
      rgen_subdirs[subdir] ||= []
      rgen_subdirs[subdir] << src
    end
  }
  if (makefile)
    File.open(makefile, 'w') { |out|
      out << <<EOS
# Generated makefile fragment.
# Including makefile defines $(rgen_dir) $(rgen_cmd) and $(specs).

rgen_generator=#{make_continue rgen_generator}
EOS
      rgen_subdirs.each_key { |subdir|
        out << "\nrgen_#{subdir}_srcs = #{make_continue(rgen_subdirs[subdir])}\n"
      }
      out << <<EOS
rgen_srcs=#{make_continue rgen_srcs}

# Header file install rules.
EOS
      ["amqp_0_10", "framing", "client/no_keyword","client", "broker"].each { |ns|
        dir="qpid/#{ns}"
        dir_ = dir.tr("/", "_")
        regex=%r|#{dir}/[^/]+\.h$|
        out << <<EOS
#{dir_}dir = $(includedir)/#{dir}
dist_#{dir_}_HEADERS = #{make_continue rgen_srcs.grep(regex)}

EOS
      } # each
    }   # File makefile
  end   # if (makefile)

  if (cmakefile)
    File.open(cmakefile, 'w') { |out|
      out << <<EOS
# Generated makefile fragment.
# Including makefile defines ${rgen_dir} ${rgen_cmd} and ${specs}.

set(rgen_generator #{cmake_continue cmake_rgen_generator})
EOS
      rgen_subdirs.each_key { |subdir|
        out << "\nset(rgen_#{subdir}_srcs #{cmake_continue(rgen_subdirs[subdir])})\n"
      }
    }   # File makefile
  end   # if (makefile)
end
