#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
refinery_root = (defined?(REFINERY_ROOT) && REFINERY_ROOT.is_a?(Pathname) ? REFINERY_ROOT : Pathname.new(File.expand_path(File.dirname(__FILE__) << "/..")))
rails_root = (defined?(RAILS_ROOT) ? RAILS_ROOT : ARGV.first)
unless rails_root.nil? or rails_root.length == 0
  # ensure asset directories exist.
  dirs = [%w(public stylesheets), %w(public javascripts), %w(db migrate)]
  FileUtils::makedirs dirs.map {|dir| File.join(rails_root, dir) }

  # copy in the new assets.
  assets = [%w(public stylesheets refinery), %w(public javascripts refinery), %w(public javascripts wymeditor), %w(VERSION), %w(public images wymeditor skins refinery), %w(public images refinery), %w(public stylesheets wymeditor skins refinery), %w(public javascripts jquery)]
	assets.each do |asset|
	  FileUtils::rm_rf File.join(rails_root, asset), :secure => true # ensure the destination is clear.
	  FileUtils::cp_r File.join(refinery_root, asset), File.join(rails_root, asset) # copy the new assets into the project.
  end

  # copy in any new migrations.
  FileUtils::cp Dir[File.join(%W(#{refinery_root} db migrate *.rb))], File.join(%W(#{rails_root} db migrate))

  # replace rakefile and gemfile.
  FileUtils::cp File.join(%W(#{refinery_root} Rakefile)), File.join(%W(#{rails_root} Rakefile))
  unless File.exist?(File.join("%W(#{rails_root} Gemfile)"))
    FileUtils::cp File.join(%W(#{refinery_root} Gemfile)), File.join(%W(#{rails_root} Gemfile))
  else
    # TODO only override refinery gems here.
  end

  # read in the Gemfile and write it back out with the refinerycms gem enabled.
  lines = File.open(File.join(%W(#{rails_root} Gemfile)), "r").read.split("\n")
  lines.each do |line|
    line.gsub!("#gem 'refinerycms'", "gem 'refinerycms'")
  end
  # write the new content into the file.
  File.open(File.join(%W(#{rails_root} Gemfile)), "w").puts(lines.join("\n"))

  # replace the preinitializer.
  FileUtils::cp File.join(%W(#{refinery_root} config preinitializer.rb)), File.join(%W(#{rails_root} config preinitializer.rb))

  # replace the boot file.
  FileUtils::cp File.join(%W(#{refinery_root} config boot.rb)), File.join(%W(#{rails_root} config boot.rb))

  # copy the lib/refinery directory in
  FileUtils::cp_r File.join(%W(#{refinery_root} lib refinery)), File.join(rails_root, "lib")

  # get current secret key
  if !File.exist?(File.join(%W(#{rails_root} config application.rb)))
    lines = File.open(File.join(%W(#{rails_root} config environment.rb)), "r").read.split("\n")
  else
    lines = File.open(File.join(%W(#{rails_root} config application.rb)), "r").read.split("\n")
  end

  secret_key = ""
  lines.each do |line|
    match = line.scan(/(:secret)([^']*)([\'])([^\']*)/).flatten.last
    secret_key = match unless match.nil?
  end

	# read in the config files
	if File.exist?(File.join(%W(#{rails_root} config application.rb)))
	  FileUtils::cp File.join(%W(#{refinery_root} config environment.rb)), File.join(%W(#{rails_root} config environment.rb))
  else
    # write the new content into the file.
    FileUtils::cp File.join(%W(#{refinery_root} config application.rb)), File.join(%W(#{rails_root} config application.rb))

    app_rb_lines = File.open(File.join(%W(#{rails_root} config application.rb)), "r").read.split("\n")
    app_rb_lines.each do |line|
      match = line.scan(/(:secret)([^']*)([\'])([^\']*)/).flatten.last
      line.gsub!(match, secret_key) unless match.nil?
    end

    # write the new content into the file.
    File.open(File.join(%W(#{rails_root} config application.rb)), "w").puts(app_rb_lines.join("\n"))

    FileUtils::cp File.join(%W(#{refinery_root} config environment.rb)), File.join(%W(#{rails_root} config environment.rb))
  end

  unless File.exist?(File.join(%W(#{rails_root} config settings.rb)))
    FileUtils::cp(File.join(%W(#{refinery_root} config settings.rb)), File.join(%W(#{rails_root} config settings.rb)))
  end

  app_config_file = "application.rb"

	app_config = File.open(File.join(%W(#{rails_root} config #{app_config_file})), "r").read

  # copy new jquery javascripts.
  FileUtils.cp File.join(%W(#{refinery_root} public javascripts jquery.js)), File.join(%W(#{rails_root} public javascripts jquery.js))
  FileUtils.cp File.join(%W(#{refinery_root} public javascripts jquery-ui.js)), File.join(%W(#{rails_root} public javascripts jquery-ui.js))

  # backup app's config file and replace it, if required.
	environment_updated = false
  matcher = /(#===REFINERY REQUIRED GEMS===)(.+?)(#===REFINERY END OF REQUIRED GEMS===)/m
  unless (app_refinery_gems_section = app_config.scan(matcher).join("")).length == 0
    # backup the config file.
  	FileUtils.cp File.join(%W(#{rails_root} config #{app_config_file})), File.join(%W(#{rails_root} config #{app_config_file.gsub(".rb", "")}.autobackupbyrefinery.rb))

    # copy the new config file.
    FileUtils.cp File.join(%W(#{refinery_root} config #{app_config_file})), File.join(%W(#{rails_root} config #{app_config_file}))

    # Write the secret key back into the file.


  	environment_updated = true
	end

	unless ARGV.include?("--from-refinery-installer")
	  puts "---------"
	  puts "Copied new Refinery core assets."
	  if environment_updated
  	  puts "I've made a backup of your current config/#{app_config_file} file as it has been updated with the latest Refinery requirements."
  	  puts "The backup is located at config/#{app_config_file.gsub(".rb", "")}.autobackupbyrefinery.rb incase you need it."
    end
	  puts ""
	  puts "=== ACTION REQUIRED ==="
	  puts "Please run rake db:migrate to ensure your database is at the correct version."
	  puts "Please also run rake gems:install to ensure you have the currently specified gems." if environment_updated

	  puts ""
  end
else
  unless ARGV.include?("--from-refinery-installer")
    puts "Please specify the path of the refinery project that you want to update, i.e. refinery-update-core /path/to/project"
  end
end