# 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.

# This nginx.conf is designed and written for local dev environments
# It will use the blocking startup mode and console logging
worker_processes  1;
daemon off;
error_log /dev/stdout error;

events {
    worker_connections 1024;
}
http {
    lua_package_path "/skywalking-nginx-lua/lib/skywalking/?.lua;;";
    # Buffer represents the register inform and the queue of the finished segment
    lua_shared_dict tracing_buffer 100m;

    # Init is the timer setter and keeper
    # Setup an infinite loop timer to do register and trace report.
    init_worker_by_lua_block {
        local metadata_buffer = ngx.shared.tracing_buffer

        metadata_buffer:set('serviceName', 'User_Service_Name')
        -- Instance means the number of Nginx deloyment, does not mean the worker instances
        metadata_buffer:set('serviceInstanceName', 'User_Service_Instance_Name')

        require("client"):startBackendTimer("http://127.0.0.1:8080")
    }
    log_format sw_trace escape=json "$uri $request_body";

    server {
        listen 8080;

        # This is for local dev only, please do not add this in any production env.
        lua_code_cache off;

        location /ingress {
            default_type text/html;

            rewrite_by_lua_block {
                require("tracer"):start("User_Service_Name-nginx:upstream_ip:port")
            }

            proxy_pass http://127.0.0.1:8080/tier2/lb;

            body_filter_by_lua_block {
                require("tracer"):finish()
            }

            log_by_lua_block {
                require("tracer"):prepareForReport()
            }
        }

        location /tier2/lb {
            default_type text/html;

            rewrite_by_lua_block {
                require("tracer"):start("User_Service_Name-nginx:upstream_ip2:port2")
            }

            proxy_pass http://127.0.0.1:8080/backend;

            body_filter_by_lua_block {
                require("tracer"):finish()
            }

            log_by_lua_block {
                require("tracer"):prepareForReport()
            }
        }

        # ------------------------------------------------------
        # -- Mock backend business service as the upsteeam
        # ------------------------------------------------------
        location /backend {
            default_type text/html;
            content_by_lua_block {
                ngx.say("<p>Backend service for testing only.</p>")
                ngx.say("<p>Backend sw6 received headers: " .. ngx.req.get_headers()["sw6"] .. "</p>")
            }
        }


        # ------------------------------------------------------
        # -- Mock OAP server to provide register and trace collection
        # ------------------------------------------------------
        location /v2/service/register {
            default_type text/html;
            lua_need_request_body on;
            access_log /var/log/nginx/trace.log sw_trace;

            content_by_lua_block {
                local cjson = require('cjson')

                ngx.log(ngx.DEBUG, 'Service register request = ', ngx.req.get_body_data())
                local param = cjson.decode(ngx.req.get_body_data())

                local registeredInfo = {}
                registeredInfo[1] = {key=param.services[1].serviceName, value=1}
                ngx.say(cjson.encode(registeredInfo))
            }
        }

        location /v2/instance/register {
            default_type text/html;
	        access_log /var/log/nginx/trace.log sw_trace;
            lua_need_request_body on;

            content_by_lua_block {
                local cjson = require('cjson')
                ngx.log(ngx.DEBUG, 'Service instance register request = ', ngx.req.get_body_data())
                local param = cjson.decode(ngx.req.get_body_data())

                local registeredInfo = {}

                registeredInfo[1] = {key=param.instances[1].instanceUUID, value=1}
                ngx.say(cjson.encode(registeredInfo))
            }
        }

        location /v2/instance/heartbeat {
            default_type text/html;
            lua_need_request_body on;
            access_log /var/log/nginx/trace.log sw_trace;

            content_by_lua_block {
                local cjson = require('cjson')
                --ngx.log(ngx.DEBUG, 'Service instance ping request = ', ngx.req.get_body_data())
            }
        }

        location /v2/segments {
            default_type text/html;
            lua_need_request_body on;
            access_log /var/log/nginx/trace.log sw_trace;

            content_by_lua_block {
                local cjson = require('cjson')
                ngx.log(ngx.DEBUG, 'Received segment = ', ngx.req.get_body_data())
            }
        }
    }
}