# 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 'rbconfig'
require 'rake/clean'

gem 'rake-compiler'
require 'rake/extensiontask'

require 'Clownfish/CFC'

def exe_path(*args)
  File.join(args).ext(RbConfig::CONFIG["EXEEXT"])
end

def obj_path(*args)
  File.join(args).ext(RbConfig::CONFIG["OBJEXT"])
end

def cc_command
  RbConfig::CONFIG["CC"]
end

def make_command
  command = RbConfig::CONFIG["make-prog"]
  if !command
    if RUBY_PLATFORM =~ /mswin/i
      cc = cc_command
      if cc =~ /^cl\b/
        command = "nmake"
      else
        command = "dmake"
      end
    else
      command = "make"
    end
  end
  return command
end

def extra_ccflags
  ""
end

def all_ccflags
  flags = RbConfig::CONFIG["CFLAGS"] + extra_ccflags
  flags.gsub!(/"/, '\\"');
  flags
end

def run_make(dir, params)
  current_dir = Dir.pwd
  chdir(dir) if dir
  command = params.clone
  command.unshift("CC=#{cc_command}")
  if RUBY_PLATFORM =~ /mswin/i
    if cc_command =~ /^cl\b/ 
      command.unshift("-f", "Makefile.MSVC")
    else
      command.unshift("-f", "Makefile.MinGW")
    end
  end
  command.unshift(make_command)
  success = system(*command)
  if !success
    raise "Make failed"
  end
  chdir(current_dir) if dir
end

def quotify(string)
  return '"' + string.gsub(/([\\\"])/,'\\\\\\1') + '"'
end

IS_DISTRO_NOT_DEVEL  = File.directory?('core')
AUTOGEN_DIR          = "autogen"
BASE_DIR             = File.absolute_path(IS_DISTRO_NOT_DEVEL ? '.' : '..')
COMMON_SOURCE_DIR    = File.join(BASE_DIR, "common")
CHARMONIZER_C        = File.join(COMMON_SOURCE_DIR, 'charmonizer.c')
CHARMONIZER_EXE_PATH = File.absolute_path(exe_path('charmonizer'))
CHARMONY_H_PATH      = "charmony.h"
CHARMONY_RB_PATH     = "Charmony.rb"
CORE_SOURCE_DIR      = File.join(BASE_DIR, "core")

desc "Build clownfish"
task :clownfish => [:charmony] do
    puts "Parsing Clownfish files...\n";
    hierarchy_obj = compile_clownfish
    core_binding_obj = Clownfish::CFC::Binding::Core.new(
        :hierarchy => hierarchy_obj,
        :header    => autogen_header,
        :footer    => '',
    )

    puts "Writing Clownfish autogenerated files...\n"
    modified = core_binding_obj.write_all_modified

end

desc "Build and run charmonizer, creating charmony.h and charmony.rb"
task :charmony do
  # Compile charmonizer executable.
  if !uptodate? CHARMONIZER_EXE_PATH, [CHARMONIZER_C]
    outflag = cc_command.match(/cl\b/) ? "/Fe" : "-o "
    command = "#{cc_command} #{outflag}#{CHARMONIZER_EXE_PATH} #{CHARMONIZER_C}"
    puts command
    if !system(command)
      raise "Failed to compile #{CHARMONIZER_EXE_PATH}"
    end
  end

  # Return if charmonizer output is current.
  if uptodate? CHARMONY_RB_PATH, [CHARMONIZER_EXE_PATH]
    next
  end
  puts "Running #{CHARMONIZER_EXE_PATH}...\n"

  # Prepare arguments to charmonizer.
  command = [
    CHARMONIZER_EXE_PATH,
    '--cc=' + cc_command,
    '--enable-c',
    '--enable-ruby',
    '--',
    all_ccflags,
  ]
  if (ENV['CHARM_VALGRIND'])
    command.unshift("valgrind", "--leak-check=yes")
  end

  # Run charmonizer.
  puts command.join(" ")
  if !system(*command)
    raise "Failed to run #{CHARMONIZER_EXE_PATH}: " + $?.to_s
  end
end
CLEAN.include(CHARMONIZER_EXE_PATH)
CLEAN.include(CHARMONY_H_PATH)
CLEAN.include(CHARMONY_RB_PATH)
# Clean up after charmonizer if it doesn't succeed on its own.
CLEAN.include("_charm*")

# Clean up after MSVC.
CLEAN.include("*.pdb")

def autogen_header 
    return <<"END_AUTOGEN";
/***********************************************

 !!!! DO NOT EDIT !!!!

 This file was auto-generated by Rakefile

 ***********************************************/

/* 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.
 */

END_AUTOGEN

end

def compile_clownfish  
    hierarchy_obj = Clownfish::CFC::Model::Hierarchy.new(:dest => AUTOGEN_DIR)
    hierarchy_obj.add_source_dir(CORE_SOURCE_DIR)
    if (ENV['CLOWNFISH_INCLUDE'])
      hierarchy_obj.add_include_dir(ENV['CLOWNFISH_INCLUDE'])
    end
    hierarchy_obj.build
    
    return hierarchy_obj
end


