require 'thor'
require 'fileutils'
require 'fwtoolkit/config'
require 'fwtoolkit/projectfile'
require 'fwtoolkit/cli/fw_actions'
require 'fwtoolkit/cli/thorutils'
require 'xcodebuild'

# This little hack is necesary to use XcodeBuild outside the context of rake
module XcodeBuild
  module Tasks
    class BuildTask 
      def define; end

      def build!; xcodebuild :build end
      def archive!; xcodebuild :archive end
      def clean!; xcodebuild :clean end
    end
  end
end

module FWToolkit
  class Xcode < Thor
    include Thor::Actions
    include FWToolkit::ThorUtils
    source_root_templates!

    desc "new [LANGUAGE] [PROJECT_NAME] [CLASS_PREFIX]", "Create a new Xcode project with FW's settings"
    def new(project_language, project_name, class_prefix, root_dir=File.join(Dir.pwd, project_name))
      say 'Creating Xcode project'
      destination_root = root_dir

      #raise Thor::Error, "Can't create the project. The directory #{destination_root} already exists" if Dir.exist?(destination_root)

      Projectfile.load_with_config! :project_name => project_name, :class_prefix => class_prefix.upcase

      template_config = { :target_platform => Config.target_platform,
                          :organization_name => Config.organization_name,
                          :project_creator => Config.developer_name } 
      template_config.merge! Projectfile.config 
      template_directory "templates/#{project_language}_project/xcode", destination_root, template_config
    end

    desc "build [PROJECT_NAME]", "Compile a version of the Xcode project"
    option :clean,
           :type => :boolean,
           :desc => 'Clean the project before building',
           :default => true
    option :archive,
           :type => :boolean, 
           :desc => 'Archive the project after building',
           :default => false
    option :type,
           :banner => 'type of build',
           :desc => "The kind of build can be one of the following: dev, testing, release. Default: dev",
           :default => 'dev'
    option :sdk,
           :banner => 'iphoneos/iphonesimulator',
           :desc => "The platform to buy for: iphoneos or iphonesimulator. Default: iphoneos",
           :default => 'iphoneos'
    def build(project_dir)
      build_types = ['dev', 'testing', 'release']
      raise Thor::Error, 'Build type should be one of the following: dev, testing, release' unless build_types.include?(options[:type].downcase) 

      Projectfile.load! project_dir
      output_dir = File.join artifacts_dir_for_project(Config.project_name), Projectfile.project_name
      say_status :run, "Compiling the project and putting the output in: #{output_dir}", :blue

      t = XcodeBuild::Tasks::BuildTask.new
      t.invoke_from_within = 'project_dir'
      t.sdk = options[:sdk]
      t.workspace = Projectfile.xcode_workspace
      t.scheme = Projectfile.xcode_scheme[options[:type].to_sym]
      t.formatter = XcodeBuild::Formatters::ProgressFormatter.new
      t.add_build_setting 'CONFIGURATION_BUILD_DIR', output_dir

      if options[:clean]
        FileUtils.rm_rf output_dir
        t.clean!
      end
      options[:archive] ? t.archive! : t.build!
    end


    private
    def artifacts_dir_for_project(project_name)
      File.join  Config.artifacts_tmp_dir, project_name
    end
  end
end

#            :project_name -> OracleProject
#            :binary_name -> OracleProject.app
#            :class_prefix -> FWO
#            :target_platform -> 6.0
#            :provisioning
#
#binary_name  -> app_name.app
#target_name  -> app_name
#tests_target_name -> app_nameTests
#class_prefix -> XXX
#project_name -> app_name
#workspace_name -> app_name
#project_creator -> dev_name
#organization_name -> Future Workshops