<%=
  require 'json'

nats_err_msg = <<-TEXT
Using nats (instead of nats-tls) is deprecated. The nats process will
be removed soon. Please migrate to using nats-tls as soon as possible.
If you must continue using nats for a short time you can set the
nats.fail_if_using_nats_without_tls property on route_registrar to
false.
TEXT
  nats_link_name = 'nats'
  if p('nats.tls.enabled')
    nats_link_name = 'nats-tls'
  else
    if p('nats.fail_if_using_nats_without_tls')
      raise nats_err_msg
    end
  end

  nats_machines = nil
  if_p('nats.machines') do |ips|
    nats_machines = ips.compact
  end.else_if_link(nats_link_name) do |nats_link|
    nats_link.if_p("nats.hostname") do |hostname|
      nats_machines = [hostname]
    end.else do
      nats_machines = nats_link.instances.map { |instance| instance.address }
    end
  end

  nats_port = nil
  if_p('nats.port') do |prop|
    nats_port = prop
  end.else_if_link(nats_link_name) do |nats_link|
    nats_port = nats_link.p("nats.port")
  end

  nats_user = nil
  if_p('nats.user') do |prop|
    nats_user = prop
  end.else_if_link(nats_link_name) do |nats_link|
    nats_link.if_p("nats.user") do |prop|
      nats_user = prop
    end
  end

  nats_password = nil
  if_p('nats.password') do |prop|
    nats_password = prop
  end.else_if_link(nats_link_name) do |nats_link|
    nats_link.if_p("nats.password") do |prop|
      nats_password = prop
    end
  end

  message_bus_servers = nil
  if nats_user and nats_password
    message_bus_servers = nats_machines.map do |host|
      {
        host: "#{host}:#{nats_port}",
        user: "#{nats_user}",
        password: "#{nats_password}"
      }
    end
  else
    message_bus_servers = nats_machines.map do |host|
      {
        host: "#{host}:#{nats_port}"
      }
    end
  end

  routes = p('route_registrar.routes')

  routes.each_with_index do |route, index|
    if route['tls_port'] != nil && (route['server_cert_domain_san'] == nil || route['server_cert_domain_san'].length <= 0)
      raise "expected route_registrar.routes[#{index}].route.server_cert_domain_san when tls_port is provided"
    end

    if route['protocol'] != nil && (route['protocol'] != 'http1' && route['protocol'] != 'http2')
      raise "expected route_registrar.routes[#{index}].route.protocol to be http1 or http2 when protocol is provided"
    end

    if route['options'] != nil
      if (route['options']['lb_algo'] != nil && route['options']['lb_algo'] != 'least-connection' && route['options']['lb_algo'] != 'round-robin')
        raise "expected route_registrar.routes[#{index}].route.options.lb_algo to be least-connection or round-robin when provided"
      end
    end

    if route['prepend_instance_index']
      route['uris'].map! { |uri| "#{spec.index}-#{uri}" }
    end

    if route['type'] == 'sni'
      route['sni_routable_san'] = spec.address

      if route.key?('server_cert_domain_name_modifier')
        if route['server_cert_domain_name_modifier'].key?('key')
            route['sni_routable_san'] = spec.address.gsub(route['server_cert_domain_name_modifier']['key'], route['server_cert_domain_name_modifier']['value'])
        else
            raise "expected route_registrar.routes[#{index}].route.server_cert_domain_name_modifier.key when server_cert_domain_name_modifier is provided"
        end
      end
    end
  end

  host = nil
  if_p('host') do |prop|
    host = prop
  end.else do
    host = spec.ip
  end

  routing_api = {
    ca_certs: '/var/vcap/jobs/route_registrar/config/certs/ca.crt',
    client_cert_path: '/var/vcap/jobs/route_registrar/config/routing_api/certs/client.crt',
    client_private_key_path: '/var/vcap/jobs/route_registrar/config/routing_api/keys/client_private.key',
    server_ca_cert_path: '/var/vcap/jobs/route_registrar/config/routing_api/certs/server_ca.crt',
    max_ttl: '120s',
    client_id: 'routing_api_client',
  }
  oauth_endpoint = 'uaa.service.cf.internal'
  oauth_port = '8443'

  api_scheme = 'https'
  api_endpoint = 'routing-api.service.cf.internal'
  api_port = '3001'

  if_link('routing_api') do |link|
    link.if_p('routing_api.max_ttl') do |prop|
      routing_api[:max_ttl] = prop
    end

    link.if_p('routing_api.clients') do |clients|
      client_id = clients.keys.sort.first
      routing_api[:client_id] = client_id
      routing_api[:client_secret] = clients[client_id]['secret']
    end

    link.if_p('uaa.token_endpoint') do |endpoint|
      oauth_endpoint = endpoint
    end

    link.if_p('routing_api.enabled_api_endpoints') do |endpoints|
      if endpoints == 'both' or endpoints == 'mtls'
        api_scheme = 'https'
        api_port = link.p('routing_api.tls_port', api_port)
      end
    end


    link.if_p('uaa.tls_port') do |port|
      oauth_port = port
    end
  end

  if_p('route_registrar.routing_api.api_url') do |prop|
    if_link('routing_api') do |link|
      if link.p('routing_api.enabled_api_endpoints') == "mtls" and not prop.start_with?('https')
          raise 'expected route_registrar.routing_api.api_url to be https when routing_api.enabled_api_endpoints is mtls only'
      end
    end

    routing_api[:api_url] = prop
  end.else do
    routing_api[:api_url] = "#{api_scheme}://#{api_endpoint}:#{api_port}"
  end
  if_p('route_registrar.routing_api.oauth_url') do |endpoint|
    routing_api[:oauth_url] = endpoint
  end.else do
    routing_api[:oauth_url] = "https://#{oauth_endpoint}:#{oauth_port}"
  end
  if_p('route_registrar.routing_api.client_id') do |prop|
    routing_api[:client_id] = prop
  end
  if_p('route_registrar.routing_api.client_secret') do |prop|
    routing_api[:client_secret] = prop
  end


  routing_api['skip_ssl_validation'] = p('route_registrar.routing_api.skip_ssl_validation')

  nats_mtls_config = {
     enabled: p('nats.tls.enabled'),
     cert_path: '/var/vcap/jobs/route_registrar/config/nats/certs/client.crt',
     key_path: '/var/vcap/jobs/route_registrar/config/nats/certs/client_private.key',
     ca_path: '/var/vcap/jobs/route_registrar/config/nats/certs/server_ca.crt'
  }

  config = {
    message_bus_servers: message_bus_servers,
    nats_mtls_config: nats_mtls_config,
    host: host,
    routes: routes,
    dynamic_config_globs: p('route_registrar.dynamic_config_globs'),
    routing_api: routing_api,
    availability_zone: spec.az,
  }
  JSON.pretty_generate(config)
%>
