#!/usr/bin/env ruby
#
# Copyright (c) 2010 Stefan Kurtz <kurtz@zbh.uni-hamburg.de>
# Copyright (c) 2010 Center for Bioinformatics, University of Hamburg
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

require 'ostruct'
require 'optparse'
require 'fileutils'

def usage(opts,msg)
  STDERR.puts "#{$0}: #{msg}\n#{opts.to_s}"
  exit 1
end

def parseargs(argv)
  options = OpenStruct.new
  options.optimize = true
  options.m64 = true
  options.speed = false
  options.prof = false
  options.jobs = 1
  options.fileargs = nil
  options.threads = true
  options.sketch = false
  opts = OptionParser.new
  opts.on("--sketch","compile with annotation sketch") do |x|
    options.sketch = true
  end
  opts.on("--m64","compile 64 bit binary") do |x|
    options.m64 = true
  end
  opts.on("--m32","compile 32 bit binary") do |x|
    options.m64 = false
  end
  opts.on("--speed","optimize for speed") do |x|
    options.speed = true
  end
  opts.on("--prof","compile for profiling") do |x|
    options.prof = true
  end
  opts.on("--noopt","no optimization") do |x|
    options.optimize = false
  end
  opts.on("--nothreads","compilation without threaded code") do |x|
    options.threads = false
  end
  opts.on("-j","--j NUM","run jobs in given number of threads") do |x|
    options.jobs = x.to_i
  end
  rest = opts.parse(argv)
  if not rest.empty?
    options.fileargs = rest
  end
  return options
end

def makecompilerflags(fp,options)
  wrapmemcpy=""
  extracpp = ""
  if ENV.has_key?("systemdef") and ENV["systemdef"] != "Darwin"
    # wrapmemcpy="wrapmemcpy=yes"
    # extracpp = "CPPFLAGS='-U_FORTIFY_SOURCE -D_GNU_SOURCE -fno-stack-protector'"
  end
  fp.print "all:\n\t\${MAKE} -j #{options.jobs} #{wrapmemcpy} with-sqlite=no"
  # fp.print " CFLAGS+=-fstrict-aliasing"
  if options.speed
    fp.print " assert=no amalgamation=yes"
  end
  if options.m64
    fp.print " 64bit=yes"
  end
  if options.prof
    fp.print " prof=yes"
  end
  if not options.optimize
    fp.print " opt=no"
  end
  if options.threads
    fp.print " threads=yes"
  end
  if ENV.has_key?("SKETCH") and ENV["SKETCH"] == "yes"
    fp.print " cairo=yes"
  else
    fp.print " cairo=no"
  end
  compiler="cc"
  if ENV.has_key?("CC")
    compiler=ENV["CC"]
  end
  fp.print " #{extracpp} popcnt=yes CC='ccache " + compiler + "'"
  if not options.fileargs.nil?
    filenames=options.fileargs.join(" ")
    fp.puts " #{filenames}"
  else
    fp.puts ""
  end
end

if File.exist?('LocalMakefile')
  FileUtils.mv('LocalMakefile','LocalMakefile.previous')
end

options = parseargs(ARGV)

File.open('LocalMakefile',"w") do |fp|
  makecompilerflags(fp,options)
end

if File.exist?('LocalMakefile.previous') and
     not FileUtils.compare_file('LocalMakefile','LocalMakefile.previous')
  STDERR.puts "LocalMakefile and LocalMakefile.previous files differ: first " +
              "remove these"
  exit 1
end

sleep(1)
system("make -f LocalMakefile")
