#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

server {
    listen 8080 default_server;

    server_tokens off;
    ignore_invalid_headers off;
    proxy_ssl_server_name on;

    #turn off the uninitialized_variable_warn ,as it writes to error_log , hence io
    uninitialized_variable_warn off;

    # block ips of embargoed countries
    if ( $blacklist ) {
        return 403;
    }

    include /etc/api-gateway/conf.d/commons/common-headers.conf;
    include /etc/api-gateway/conf.d/includes/resolvers.conf;

    # Log locations with service name
    access_log /var/log/api-gateway/access.log platform;
    error_log /var/log/api-gateway/gateway_error.log debug;

    # include environment variable

    error_page 500 501 502 503 504 /50x.html;

    location /50x.html {
        more_set_headers 'Content-Type: application/json';
        more_set_headers 'X-Request-Id: $requestId';
        more_set_headers 'X-Gateway-Host: $gateway_host';
        return 500 '{"code":$status, "message":"Oops. Something went wrong. Check your URI and try again."}\n';
    }

    location = /api {
        content_by_lua '
            ngx.say("You have hit the api gateway managed endpoints.")
        ';
    }

    location ~ "^/api/([a-zA-Z0-9\-]+)/([a-zA-Z0-9\-\/\.\_\{\} ]+)(\\b)" {
        set $upstream https://172.17.0.1;
        set $tenant $1;
        set $tenantNamespace '';
        set $tenantInstance '';
        set $apiId '';
        set $backendUrl '';
        set $apiKey '-';
        set $gatewayPath $2;
        set $analyticsUri '';
        set $cors_origins '';
        set $cors_methods '';
        set $requestHeaders '';
        set $requestBody '';
        set $responseHeaders '';
        set $responseBody '';

        proxy_read_timeout 70s;
        client_max_body_size 5m;

        access_by_lua_block {
            local routing = require "routing"
            local ds = require "lib/dataStore"
            routing.processCall(ds.init())
        }

        proxy_pass $upstream;
        header_filter_by_lua_block {
            local cors = require "cors"
            cors.replaceHeaders()
        }

        body_filter_by_lua_block {
          local routing = require "routing"
          if ngx.req.get_headers()["x-debug-mode"] == "true" then
            routing.setResponseLogs()
          end
        }
    }

    location = /health {
        access_log off;
        proxy_pass http://0.0.0.0:9000/v1/health-check;
    }
}
