require 'json'
require 'logger'
require 'trace-component'
require 'pathname'
require 'helper-run-class'
require 'prepare-environment'

class PlanStep
    def initialize ()
        @basePath = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}/"
        @log = Logger.new(Canzea::config[:logging_root] + '/plans.log')
    end

    def runPhaseInstall (role, solution, test, task)

        plan = JSON.parse("{ \"plan\": [ { \"role\": \"#{role}\", \"solution\": \"#{solution}\" } ] }")

        ENV['ES_ROLE'] = role;
        ENV['ES_SOLUTION'] = solution;

        n = Worker.new
        n.test ( test )

        start = Integer(task)
        lines = 1

        cmd = "undefined"

        begin

            plan['plan'].each do |item|
                @log.info(item['solution'])

                root = "#{@basePath}/roles/#{item['role']}/#{item['solution']}"
                if File.exist?(root) == false
                    puts "-- ERROR #{root} does not exist!"
                    raise "#{root} does not exist!"
                end

                cmd = "#{@basePath}/roles/#{item['role']}/#{item['solution']}/install.sh"
                if File.exist?(cmd)
                    lines = n.run cmd, start, lines - 1

                    @log.info "#{ lines } lines read"
                end
            end
        rescue => exception
            @log.error(cmd)
            @log.error(exception.to_s)
            @log.error(exception.backtrace)
            abort()
        end
    end

    def runPhaseConfigure (role, solution, test, task, ref="")

        plan = JSON.parse("{ \"plan\": [ { \"role\": \"#{role}\", \"solution\": \"#{solution}\" } ] }")

        ENV['ES_REF'] = ref;
        ENV['ES_ROLE'] = role;
        ENV['ES_SOLUTION'] = solution;

        n = Worker.new
        n.test ( test )

        start = Integer(task)
        lines = 1

        cmd = "undefined"

        begin

            plan['plan'].each do |item|

                root = "#{@basePath}/roles/#{item['role']}/#{item['solution']}"
                if File.exist?(root) == false
                    log "-- ERROR #{root} does not exist!"
                    raise "#{root} does not exist!"
                end

                if (test == false)
                    # Register the service with Consul, if consul is ready
                    # If metadata.json exists, then use the information to register
                    cmd = "#{@basePath}/roles/#{item['role']}/#{item['solution']}/metadata.json"
                    if File.exist?(cmd)
                        md = File.read(cmd)
                        md = JSON.parse(md)
                        if (md['services'].size() > 0)
                            svc = md['services'][0]

                            adef = {
                                "listener"=>svc['listener'],
                                "name" => "#{svc['name']}",
                                "id" => "#{ENV['HOSTNAME']}-#{svc['name']}",
                                "tags"=>[ item['role'] ],
                                "port"=>svc['port']
                            }
                            log "-- Registering #{svc['name']}"
                            h = HelperRun.new false
                            h.run "consul", "register_service", JSON.generate(adef)
                        end
                    end

                    envScript = "#{@basePath}/roles/#{item['role']}/#{item['solution']}/environment.json"
                    if File.exist?(envScript)
                        envPush = PrepareEnvironment.new false
                        envPush.addToEnv "#{envScript}"
                    end

                end

                cmd = "#{@basePath}/roles/#{item['role']}/#{item['solution']}/configure.sh"
                if File.exist?(cmd)
                  lines = n.run cmd, start, lines - 1, false, ref
                end

                cmd = "#{@basePath}/roles/#{item['role']}/#{item['solution']}/enable.sh"
                if File.exist?(cmd)
                  lines = n.run cmd, start, lines - 1, false, ref
                end

                cmd = "#{@basePath}/roles/#{item['role']}/#{item['solution']}/status.sh"
                if File.exist?(cmd)
                  lines = n.run cmd, start, lines - 1, true, ref
                end

            end
        rescue => exception
            @log.error(cmd)
            @log.error(exception.to_s)
            @log.error(exception.backtrace)
            abort()
        end
    end


    def runPhasePatch (role, solution, test, task, ref="")

        plan = JSON.parse("{ \"plan\": [ { \"role\": \"#{role}\", \"solution\": \"#{solution}\" } ] }")

        ENV['ES_REF'] = ref;
        ENV['ES_ROLE'] = role;
        ENV['ES_SOLUTION'] = solution;

        n = Worker.new
        n.test ( test )

        start = Integer(task)
        lines = 1

        cmd = "undefined"

        commit = ENV['CATALOG_COMMIT']

        # patches/<commit>/role/solution
        begin

            plan['plan'].each do |item|

                root = "#{@basePath}/#{commit}/#{item['role']}/#{item['solution']}"
                if File.exist?(root) == false
                    log "-- WARNING #{root} does not exist"
                else

                    if (test == false)

                        envScript = "#{root}/environment.json"
                        if File.exist?(envScript)
                            envPush = PrepareEnvironment.new false
                            envPush.addToEnv "#{envScript}"
                        end

                    end

                    ENV.store('SCRIPT_PATH', root)

                    cmd = "#{root}/patch.sh"
                    if File.exist?(cmd)
                      lines = n.run cmd, start, lines - 1, false, ref
                    end
                end
            end
        rescue => exception
            @log.error(cmd)
            @log.error(exception.to_s)
            @log.error(exception.backtrace)
            abort()
        end
    end

    def log (msg)
        puts msg
        @log.info(msg)
    end

end