require 'json'
require 'logger'
require 'net/http'
require "trace-runner"
require "registry"


class PrepareEnvironment
    def initialize (_raw = false)
        @raw = _raw;
    end

    def addToEnv (envFile)
        log = Logger.new(Canzea::config[:logging_root] + '/plans.log')

        r = Registry.new

        file = File.read(envFile)

        serviceLookups = JSON.parse(file)

        if (serviceLookups.has_key?('environment'))
            serviceLookups['environment'].each do |svc|

              pputs "-- Setting...#{svc['name']}"
              log.info("Setting: " + svc['name'])
              ENV.store(svc['name'], svc['value'])
            end
        end

        serviceLookups['keyvalues'].each do |svc|

          pputs("-- Looking up...#{svc['name']}")

          uri = URI.parse(ENV["CONSUL_URL"] + '/v1/kv/' + svc['name'])
          http = Net::HTTP.new(uri.host, uri.port)

          if (Canzea::config[:consul_tls])
              pemCert = File.read(Canzea::config[:consul_tls_cert_file])
              pemKey = File.read(Canzea::config[:consul_tls_key_file])

              http.use_ssl = true
              http.ca_file = Canzea::config[:consul_tls_ca_file]
              http.cert = OpenSSL::X509::Certificate.new(pemCert)
              http.key = OpenSSL::PKey::RSA.new(pemKey)
              http.verify_mode = OpenSSL::SSL::VERIFY_PEER
              # http.set_debug_output($stdout)
              http.ssl_version = :SSLv23
          end
          request = Net::HTTP::Get.new(uri.request_uri)
          resp = http.request(request)

          if Integer(resp.code) != 200
            log.warn("KEY VALUE NOT FOUND! " + svc['name'])
            puts "-- KEY VALUE NOT FOUND! " + svc['name']
            abort("Problem, response code #{resp.code}")
          end

          result = JSON.parse(resp.body)
          s = Base64.decode64(result[0]["Value"])

          if (s.nil? == false)
            # puts s

            key = "" + svc['name'].upcase
            key = key.gsub(/\./, '').gsub(/-/, '_').gsub(/\//, '_')
            log.info("Setting: " + key + " : " + s)
            ENV.store(key, s)
          else
            log.warn("KEY VALUE NOT FOUND! " + svc['name'])
            pputs "-- KEY VALUE NOT FOUND! " + svc['name']
            abort()
          end
        end


        serviceLookups['services'].each do |svc|

          pputs "-- Looking up...#{svc['name']}"

          uri = URI.parse(ENV["CONSUL_URL"] + '/v1/catalog/service/' + svc['name'])
          http = Net::HTTP.new(uri.host, uri.port)

          if (Canzea::config[:consul_tls])
              pemCert = File.read(Canzea::config[:consul_tls_cert_file])
              pemKey = File.read(Canzea::config[:consul_tls_key_file])

              http.use_ssl = true
              http.ca_file = Canzea::config[:consul_tls_ca_file]
              http.cert = OpenSSL::X509::Certificate.new(pemCert)
              http.key = OpenSSL::PKey::RSA.new(pemKey)
              http.verify_mode = OpenSSL::SSL::VERIFY_PEER
              # http.set_debug_output($stdout)
              http.ssl_version = :SSLv23
          end
          request = Net::HTTP::Get.new(uri.request_uri)
          resp = http.request(request)

          services = JSON.parse(resp.body)

          if (services.nil? == false)

            services.each { | s |

                key = "" + svc['name'].upcase + "_ADDRESS"
                key = key.gsub(/\./, '')
                log.info("Setting: " + key + " : " + s["ServiceAddress"])
                ENV.store(key, s["ServiceAddress"])

                key = "" + svc['name'].upcase + "_PORT"
                key = key.gsub(/\./, '')
                log.info("Setting: " + key + " : " + String(s["ServicePort"]))
                ENV.store(key, String(s["ServicePort"]))

                key = "" + svc['name'].upcase + "_URL"
                key = key.gsub(/\./, '')
                val = "http://" + s["ServiceAddress"] + ":" + String(s["ServicePort"])
                log.info("Setting: " + key + " : " + val)
                ENV.store(key, val)
            }
          else
            log.warn("SERVICE NOT FOUND! " + svc['name'])
            pputs "-- SERVICE NOT FOUND! " + svc['name']
            abort()
          end
        end

        serviceLookups['secrets'].each do |svc|

          pputs "-- Looking up secret...#{svc['name']}"

          uri = URI.parse(ENV["VAULT_URL"] + '/v1/secret/' + svc['name'])
          http = Net::HTTP.new(uri.host, uri.port)

          if (Canzea::config[:consul_tls])

              pemCert = File.read(Canzea::config[:vault_tls_cert_file])
              pemKey = File.read(Canzea::config[:vault_tls_key_file])

              http.use_ssl = true
              http.ca_file = Canzea::config[:consul_tls_ca_file]
              http.cert = OpenSSL::X509::Certificate.new(pemCert)
              http.key = OpenSSL::PKey::RSA.new(pemKey)
              http.verify_mode = OpenSSL::SSL::VERIFY_PEER
              # http.set_debug_output($stdout)
              http.ssl_version = :SSLv23
          end

          request = Net::HTTP::Get.new(uri.request_uri)

          request['X-Vault-Token'] = ENV["VAULT_TOKEN"]
          request['Content-type'] = 'application/json'

          resp = http.request(request)

          # puts resp.body

          if (Integer(resp.code) == 200)

            data = JSON.parse(resp.body)

            s = data['data']
            s.each do |k|
              key = "" + svc['name'].upcase + "_" + k[0].upcase
              key = key.gsub(/\./, '').gsub(/-/, '_').gsub(/\//, '_')

              log.info("Setting: " + key)
              ENV.store(key, k[1])
            end
          else
            log.warn( "SECRET NOT FOUND! " + svc['name'])
            log.warn( "ERROR FROM VAULT " + resp.body)
            pputs "-- SECRET NOT FOUND! " + svc['name']
            pputs "-- ERROR FROM VAULT " + resp.body
            abort()
          end
        end
    end

    def print ()
        ENV.each_pair { |name,value|
            puts name + " = " + value
        }
    end

    def pputs (s)
        if (@raw == false)
            puts "-- #{s}"
        end
    end

end