# 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)
        -- set ignoreSuffix, If the operation name(HTTP URI) of the entry span includes suffixes in this set, this segment would be ignored. Multiple values should be separated by a comma(',').
        -- require("skywalking.util").set_ignore_suffix(".jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.svg")
        -- set randomseed
        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()

        -- If there is a bug of this `tablepool` implementation, we can
        -- disable it in this way
        -- require("skywalking.util").disable_tablepool()

        skywalking_tracer = require("skywalking.tracer")
    }

    server {
        listen 8090;

        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
                ------------------------------------------------------
                skywalking_tracer:start("upstream service")
                -- If you want correlation custom data to the downstream service
                -- skywalking_tracer:start("upstream service", {custom = "custom_value"})
            }

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

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

            log_by_lua_block {
                skywalking_tracer:prepareForReport()
            }
        }

        location /tier2/lb {
            default_type text/html;

            rewrite_by_lua_block {
                skywalking_tracer:start("backend service")
            }

            proxy_pass http://127.0.0.1:8090/backend;

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

            log_by_lua_block {
                skywalking_tracer:prepareForReport()
            }
        }
        # ------------------------------------------------------
        # -- Test suffix of static resources. like: /suffix/suffix.js, /suffix/suffix.css.
        # -- When suffixes set, this segment would be ignored.
        # ------------------------------------------------------
        location /suffix {

            default_type text/html;
            content_by_lua_block {
                ngx.say("<p>Suffix for testing only.</p>")
            }
            
            rewrite_by_lua_block {
                skywalking_tracer:start("backend service")
            }

            body_filter_by_lua_block {
                skywalking_tracer:finish()
            }

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