# 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')
        -- type 'boolean', mark the entrySpan include host/domain
        metadata_buffer:set('includeHostInEntrySpan', false)

        require("skywalking.util").set_randomseed()
        require("skywalking.client"):startBackendTimer("http://127.0.0.1:8080")

        -- Any time you want to stop reporting metrics, call `destroyBackendTimer`
        -- require("skywalking.client"):destroyBackendTimer()
    }

    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())
            }
        }
    }
}
