# 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 debug;

events {
    worker_connections 1024;
}
http {
    lua_package_path "/Users/wusheng/Documents/GitHub/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")
    }

    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 {
                ------------------------------------------------------
                -- NOTICE, this should be changed manually
                -- This variable represents the upstream logic address
                -- Please set them as service logic name or DNS name
                --
                -- Currently, we can not have the upstream real network address
                ------------------------------------------------------
                require("tracer"):start("upstream service")
            }

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

            body_filter_by_lua_block {
                if ngx.arg[2] then
                    require("tracer"):finish()
                end
            }

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

        location /tier2/lb {
            default_type text/html;

            rewrite_by_lua_block {
                require("tracer"):start("backend service")
            }

            proxy_pass http://127.0.0.1:8080/backend;

            body_filter_by_lua_block {
                if ngx.arg[2] then
                    require("tracer"):finish()
                end
            }

            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;

            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;
            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;

            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;

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