#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

$lib = File.expand_path('../lib', File.dirname(__FILE__))
$LOAD_PATH.unshift($lib)

require "Models/AppleConfig"
require "Models/AndroidConfig"
require "Models/Processor"
require "Helper"
require "ZLogger"
require "AppleFetcher"
require "AndroidFetcher"
require "optparse"
require "yaml"

class Main
    def initialize

        ARGV << '-r' if ARGV.empty?

        OptionParser.new do |opts|
            opts.banner = "Usage: ZReviewTender [options]"

            basePath = ENV['PWD'] || ::Dir.pwd
            defaultConfigDirName = "config"
            defaultAppleConfigFileName = "apple.yml"
            defaultAndroidConfigFileName = "android.yml"
        
            opts.on('-a', '--apple[=CONFIGYMLFILEPATH]', 'execute apple platform with config yml file') do |configYMLFilePath|
                if configYMLFilePath.nil?
                    configYMLFilePath = "#{basePath}/#{defaultConfigDirName}/#{defaultAppleConfigFileName}"
                end
                configFileCheck(configYMLFilePath, "--apple=CONFIG_YML_FILE_PATH")

                fetcher = parseConfigYMLFile(configYMLFilePath)
                fetcher.execute()
            end 

            opts.on('-g', '--googleAndroid[=CONFIGYMLFILEPATH]', 'execute android platform with config yml file') do |configYMLFilePath|
                if configYMLFilePath.nil?
                    configYMLFilePath = "#{basePath}/#{defaultConfigDirName}/#{defaultAndroidConfigFileName}"
                end
                configFileCheck(configYMLFilePath, "--googleAndroid=CONFIG_YML_FILE_PATH")

                fetcher = parseConfigYMLFile(configYMLFilePath)
                fetcher.execute()
            end 
            
            opts.on('-r', '--run=[=CONFIGFOLDERNAME]', 'execute both android and apple, specify an /config folder name') do |configFolderName|
                if configFolderName.nil?
                    configFolderName = defaultConfigDirName
                end
                androidConfigFilePath = "#{basePath}/#{configFolderName}/#{defaultAndroidConfigFileName}"
                configFileCheck(androidConfigFilePath, "--googleAndroid=CONFIG_YML_FILE_PATH")
                
                fetcher = parseConfigYMLFile(androidConfigFilePath)
                fetcher.execute()
                
                #
                
                appleConfigFilePath = "#{basePath}/#{configFolderName}/#{defaultAppleConfigFileName}"
                configFileCheck(appleConfigFilePath, "--apple=CONFIG_YML_FILE_PATH")

                fetcher = parseConfigYMLFile(appleConfigFilePath)
                fetcher.execute()
            end 
        end.parse!
    end

    private
    def configFileCheck(path, command)
        if !File.exists? path
            puts "Make sure you have vaild config file at #{path}"
            puts "Or use ZReviewTender #{command} specify config.yml file path"
            raise "Config file not found: #{path}"
        end
    end

    private
    def parseConfigYMLFile(configFilePath)
        configYMLObj = YAML.load_file(configFilePath)
        begin
            platform = Helper.unwrapRequiredParameter(configYMLObj, 'platform')
            
            fetcher = nil
            if platform.downcase == "apple"
                fetcher = AppleFetcher.new(AppleConfig.new(configYMLObj, configFilePath, ENV['PWD'] || ::Dir.pwd))
            elsif platform.downcase == "android"
                fetcher = AndroidFetcher.new(AndroidConfig.new(configYMLObj, configFilePath, ENV['PWD'] || ::Dir.pwd))
            else
                raise "unknow platform #{platform} in yml file #{configFilePath}."
            end

            processors = Helper.unwrapRequiredParameter(configYMLObj, 'processors')
            if processors.nil?
                processors = []
            end

            if processors.length < 1
                raise "must specify/enable at least one processor."
            end

            processors.each do |processor|
                processor.each do |key, value|
                    if value["enable"] != true
                        next
                    end
                    processorClass = Helper.unwrapRequiredParameter(value, "class")
                    require "Processors/#{processorClass}"
                    fetcher.registerProcessor(eval("#{processorClass}.new(#{value}, '#{configFilePath}', '#{ENV['PWD'] || ::Dir.pwd}')"))
                end
            end


            return fetcher
        rescue => e
            raise "#{e.message} in yml file #{configFilePath}."
        end        
    end
end

begin 
    Main.new()
rescue => e
    logger = ZLogger.new(ENV['PWD'] || ::Dir.pwd)
    title = "#Error: #{e.class} #{e.message}"
    body = e.backtrace
    
    logger.logError("===RUNTIME EXCEPTION START===")
    logger.logError(title)
    logger.logError(body)
    logger.logError("===RUNTIME EXCEPTION END===")
        
    puts title
    puts body
end