#!/usr/bin/env ruby
##--
# Copyright (c) 1996-2004, Yauheni Akhotnikau
# Copyright (c) 2004-2006, JSC Intervale
# Copyright (c) 2006-2016, The Mxx_ru Project
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#++
# This code is based on the code from RuCodeGen
# (http://www.rubyforge.org/projects/rucodegen) project.
# RuCodeGen is distributed under the following license:
#--
#
# Copyright (c) 2005-2006, Yauheni Akhotnikau
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#++


# Since v.1.6.10
#
# Template generation scripts runner.

require 'optparse'
require 'ostruct'

require 'tempfile'

require 'fileutils'

module MxxRuExternals

module Impl

# Command-line argument parsing.
#
# Returns object with the following methods:
# externals_file:: Name of file with externals definition. Could be nil.
# task:: Name of task for rake (default :install).
#
# Finishes script work is --help specified.
#
def Impl.parse_args
  result = OpenStruct.new(
      :externals_file => nil,
      :libdirs => [],
      :task => :install )

  parser = OptionParser.new

  parser.banner = <<BANNER
Mxx_ru Externals command script

Usage:

mxxruexternals [<options>] [-f externals-file] [task]

BANNER

  parser.on_head( '-I', '--libdir LIBDIR',
      'Include LIBDIR in the search path for required modules' ) do |p|
    result.libdirs << p
  end

  parser.on_head( '-f', '--rakefile NAME',
      'Name of file with externals definition' ) do |p|
    result.externals_file = p
  end

  parser.on_head( '-h', '--help', 'Show this message' ) do
    puts parser
    exit( 1 )
  end

  parser.order!( ARGV ) do |nonarg|
    # First non-option is a task name.
    result.task = nonarg
  end

  result
end

end # Impl

# Performs main work.
def MxxRuExternals.run
  options = Impl.parse_args

  if options.externals_file.nil?
    options.externals_file = 'externals.rb'
  end

  script_name = nil
  Tempfile.open('mxxruexternals-temp', '.') do |tmpf|
    script_name = tmpf.path
    puts "[Info] Generation of auxilary rakefile: #{script_name}"
    tmpf.write <<EOF
require 'mxx_ru/externals'

task :mxxru_cleanup_previous
task :mxxru_install_final_step

MxxRu::Externals::Registry.instance.turn_new_rules_on
load '#{options.externals_file}'

PREVIOUS_FILE = File.join MxxRu::Externals::EXTERNALS_STORAGE_DIR, 'previous.rb'
BAK_FILE_NAME = lambda {|n| "\#{PREVIOUS_FILE}.\#{n}.bak" }
MV_IF_EXISTS = lambda{ |from, to| mv(from, to) if File.exists?(from) }

file PREVIOUS_FILE do
  cp '#{options.externals_file}', PREVIOUS_FILE, :verbose => Rake.verbose
end

if File.exists?(PREVIOUS_FILE)
  prev_digest = Digest::MD5.file(PREVIOUS_FILE)
  curr_digest = Digest::MD5.file('#{options.externals_file}')

  if prev_digest != curr_digest
    puts "[Note] Externals description changed from the last time"
    puts "[Note] Contents of \#{PREVIOUS_FILE} will be used"

    task :mxxru_cleanup_previous do
      MV_IF_EXISTS[BAK_FILE_NAME[4], BAK_FILE_NAME[5]]
      MV_IF_EXISTS[BAK_FILE_NAME[3], BAK_FILE_NAME[4]]
      MV_IF_EXISTS[BAK_FILE_NAME[2], BAK_FILE_NAME[3]]
      MV_IF_EXISTS[BAK_FILE_NAME[1], BAK_FILE_NAME[2]]
      mv(PREVIOUS_FILE, BAK_FILE_NAME[1])
    end

    MxxRu::Externals::Registry.instance.turn_old_rules_on
    load PREVIOUS_FILE

    task mxxru_install_final_step: [PREVIOUS_FILE]
  else
    puts "[Note] It seems there are no changes in externals description"
    puts "[Note] Contents of \#{PREVIOUS_FILE} won't be used"
  end
else
  task mxxru_install_final_step: [PREVIOUS_FILE]
end

task install: [:mxxru_cleanup_previous, :mxxru_install_final_step]
task remove: [:mxxru_cleanup_previous, :mxxru_install_final_step]
task reget: [:mxxru_cleanup_previous, :mxxru_install_final_step]

EOF
  end

  cmdline = "rake ";
  options.libdirs.each do |l| cmdline += "-I \"#{l}\" " end
  cmdline += "-f #{script_name} #{options.task}"

  puts "[Info] Launching rake with: #{cmdline}"
  system cmdline

end

end # MxxRuExternals

MxxRuExternals.run

# vim:ft=ruby:ts=2:sts=2:sw=2:expandtab

