# TODO move to functional toolchain/build tests:
#
# * resources/Empty.strings: Test that empty .strings files don't lead to build failures.

$:.unshift("../../lib")

ENV['PLATFORM'] ||= 'ios'
require "motion/project/template/#{ENV['PLATFORM']}"

ENV['output'] ||= 'pretty_spec_dox'

Motion::Project::App.setup do |app|
  app.name = 'test'
  app.frameworks += ['AddressBook', 'AddressBookUI', 'AudioToolbox', 'AVFoundation', 'CoreData', 'CoreMIDI', 'CoreLocation', 'GameKit']
  app.vendor_project('vendor/code', :static)

  app.spec_files.insert(1, *FileList['../../lib/motion/util/version.rb', '../helpers/*.rb'])

  # Test data for (UI|NS)Application subclassing
  app.info_plist['NSPrincipalClass'] = 'ApplicationSubclass'

  if ENV['deployment_target']
    app.deployment_target = ENV['deployment_target']
  else
    ENV['deployment_target'] = app.deployment_target
  end

  File.open("/tmp/deployment_target.rb", "w") { |io|
    io.puts "ENV['deployment_target'] = '#{ENV['deployment_target']}'"
  }
  app.files.unshift("/tmp/deployment_target.rb")

  if ENV['ARCH']
    app.archs[app.local_platform] = [ENV['ARCH']]
    app.archs['iPhoneOS'] = [ENV['ARCH']] if ENV['ARCH'] =~ /arm/
  end

  # 10.8 and 10.9 are 64-bit only.
  if ENV['PLATFORM'] == 'osx' && ENV['ARCH'] == 'i386' && %w{ 10.8 10.9 }.include?(ENV['deployment_target'])
    $stderr.puts "There is no 32-bit support for OS X #{ENV['deployment_target']}."
    exit 1
  end
end

task :clean do
  if ENV['ARCH']
    dir = "./vendor/code/build-#{App.config.local_platform}"
    if File.exist?(dir)
      App.info 'Delete', dir
      FileUtils.rm_rf dir
    end
  end
end

XCODE_PLATFORMS_DIR = (ENV['XCODE_PLATFORMS_DIR'] || '/Applications/Xcode.app/Contents/Developer/Platforms')

sim_sdks = Dir.glob(File.join(XCODE_PLATFORMS_DIR, 'iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator?*.sdk')).map do |path|
  File.basename(path).scan(/^iPhoneSimulator(.+)\.sdk$/)[0][0]
end
ios_sdks = Dir.glob(File.join(XCODE_PLATFORMS_DIR, 'iPhoneOS.platform/Developer/SDKs/iPhoneOS?*.sdk')).map do |path|
  File.basename(path).scan(/^iPhoneOS(.+)\.sdk$/)[0][0]
end
IOS_SDK_VERSIONS = (sim_sdks & ios_sdks)

if IOS_SDK_VERSIONS.empty?
  $stderr.puts "Can't locate any iOS SDK"
  exit 1
end

OSX_SDK_VERSIONS = Dir.glob(File.join(XCODE_PLATFORMS_DIR, 'MacOSX.platform/Developer/SDKs/MacOSX*.sdk')).map do |path|
  File.basename(path).scan(/^MacOSX(.+)\.sdk$/)[0][0]
end

if OSX_SDK_VERSIONS.empty?
  $stderr.puts "Can't locate any OSX SDK"
  exit 1
end

namespace :spec do
  test_fail_count = []

  task :install_aggregate_test_handler do
    at_exit do
      count = test_fail_count.inject(0) { |i, sum| sum + i }
      if test_fail_count.size > 1
        App.info "TESTING", "A total of #{count} failures/errors occurred"
      end
      exit count
    end
  end

  archs = { '32' => 'i386', '64' => 'x86_64' }

  require 'motion/util/version'
  ios7 = Motion::Util::Version.new('7')
  osx108 = Motion::Util::Version.new('10.8')

  variants = {
    'ios' => {
      '32' => IOS_SDK_VERSIONS,
      # 64-bit support was introduced in iOS 7.
      '64' => IOS_SDK_VERSIONS.select { |v| Motion::Util::Version.new(v) >= ios7 },
    },
    'osx' => {
      # 32-bit support was dropped in OS X 10.8.
      '32' => OSX_SDK_VERSIONS.select { |v| Motion::Util::Version.new(v) < osx108 },
      '64' => OSX_SDK_VERSIONS
    },
  }

  variant_tasks = []

  variants.each do |platform, bits|
    namespace platform do
      bits.each do |bit, sdk_versions|
        arch = archs[bit]
        sdk_versions.each do |sdk_version|
          namespace sdk_version do
            variant_tasks << "#{platform}:#{sdk_version}:#{bit}"

            desc "Run tests on the #{platform} #{sdk_version} SDK with arch #{bit}-bit"
            task bit => :install_aggregate_test_handler do
              App.info "TESTING", "Running test suite on the #{platform} #{sdk_version} SDK with arch #{bit}-bit"
              begin
                sh "env PLATFORM=#{platform} ARCH=#{arch} deployment_target=#{sdk_version} rake #{'clean' unless ENV['clean'] == '0'} spec"
              rescue RuntimeError
                test_fail_count << $?.exitstatus
              end

              # for Jenkins CI
              sh "rake spec:ci_output" if ENV['JENKINS_HOME'] && platform == 'ios'
            end

          end
        end
      end
    end

    desc "Run tests on #{platform}"
    task platform => variant_tasks.select { |t| t.include?(platform) }.sort
  end

  desc "Run tests on all available SDKs and archs"
  task :all => variant_tasks
end

# When running iOS test on Jenkins CI, we need to direct all output to temporary
# files. So we modify the `spec` task to do this and then print the results.
#
# Detect Jenkins CI with env var from:
# https://wiki.jenkins-ci.org/display/JENKINS/Administering+Jenkins
#
if ENV['JENKINS_HOME'] && ENV['PLATFORM'] == 'ios'
  stdout, stderr = "#{Dir.pwd}/sim-stdout.log", "#{Dir.pwd}/sim-stderr.log"
  task :create_ci_output_files do
    [stdout, stderr].each do |file|
      FileUtils.rm(file) if File.exist?(file)
      FileUtils.touch(file)
    end
    ENV['SIM_STDOUT_PATH'] = stdout
    ENV['SIM_STDERR_PATH'] = stderr
  end
  task 'spec:simulator' => :create_ci_output_files do; end

  task "spec:ci_output" do
    {
      stdout => $stdout,
      stderr => $stderr,
    }.each do |path, io|
      File.open(path, 'r') do |file|
        file.each_line do |line|
          io.puts(line)
        end
      end
    end
  end
end

# TODO enable this once full test suite works on OS X.
#task :default => 'spec:all'
