# 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/?.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("skywalking.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("skywalking.tracer"):start("upstream service")
                -- If you want correlation custom data to the downstream service
                -- require("skywalking.tracer"):start("upstream service", {custom = "custom_value"})
            }

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

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

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

        location /tier2/lb {
            default_type text/html;

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

            proxy_pass http://127.0.0.1:8080/backend;

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

            log_by_lua_block {
                require("skywalking.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 sw8 received headers: " .. ngx.req.get_headers()["sw8"] .. "</p>")
            }
        }


        # ------------------------------------------------------
        # -- Mock OAP server to provide register and trace collection
        # ------------------------------------------------------
        location /v3/management/reportProperties {
            default_type text/html;
            lua_need_request_body on;

            content_by_lua_block {
                local cjson = require('cjson')

                ngx.log(ngx.DEBUG, 'Instance report request = ', ngx.req.get_body_data())

                local reportInfo = {}
                ngx.say(cjson.encode(reportInfo))
            }
        }

        location /v3/management/keepAlive {
            default_type text/html;
            lua_need_request_body on;

            content_by_lua_block {
                local cjson = require('cjson')
                ngx.log(ngx.DEBUG, 'KeepAlive request = ', ngx.req.get_body_data())

                local keepAliveInfo = {}
                ngx.say(cjson.encode(keepAliveInfo))
            }
        }

        location /v3/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())
            }
        }
    }
}
