--
-- 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.
--
local Span = require('skywalking.span')
local TC = require('skywalking.tracing_context')
local Layer = require('skywalking.span_layer')
local Segment = require('skywalking.segment')
local Util = require("skywalking.util")
local Const = require('skywalking.constants')
local json = require('cjson.safe')

local metadata_shdict = ngx.shared.tracing_buffer
local ngx = ngx
local nginxComponentId = 6000
local Tracer = {}


function Tracer:start(upstream_name, correlation)
    local serviceName = metadata_shdict:get("serviceName")
    local serviceInstanceName = metadata_shdict:get('serviceInstanceName')
    local req_uri = ngx.var.uri
    if (Util.checkIgnoreSuffix(req_uri)) then
        local tracingContext =  TC.newNoOP()
        local ctx = ngx.ctx
        ctx.tracingContext = tracingContext
        ctx.entrySpan = Span.newNoOP()
        ctx.exitSpan = Span.newNoOP()
        ctx.is_finished = false
        return
    end

    local includeHostInEntrySpan = metadata_shdict:get('includeHostInEntrySpan')
    local tracingContext = TC.new(serviceName, serviceInstanceName, ngx.var.http_request_id)
    -- Constant pre-defined in SkyWalking main repo
    -- 6000 represents Nginx
    local contextCarrier = Util.tablepool_fetch("sw_contextCarrier")
    contextCarrier["sw8"] = ngx.var.http_sw8
    contextCarrier["sw8-correlation"] = ngx.var.http_sw8_correlation
    local time_now = ngx.now() * 1000
    local entrySpan
    if (includeHostInEntrySpan)  then
        entrySpan = TC.createEntrySpan(tracingContext, ngx.var.host .. req_uri, nil, contextCarrier)
    else
        entrySpan = TC.createEntrySpan(tracingContext, req_uri, nil, contextCarrier)
    end

    Span.start(entrySpan, time_now)
    Span.setComponentId(entrySpan, nginxComponentId)
    Span.setLayer(entrySpan, Layer.HTTP)

    Span.tag(entrySpan, 'http.method', ngx.req.get_method())
    Span.tag(entrySpan, 'http.params',
             ngx.var.scheme .. '://' .. ngx.var.host .. ngx.var.request_uri )

    ------------------------------------------------------
    contextCarrier = Util.tablepool_fetch("sw_contextCarrier")
    -- Use the same URI to represent incoming and forwarding requests
    -- Change it if you need.
    local exitSpan = TC.createExitSpan(tracingContext, req_uri, entrySpan)
    Span.start(exitSpan, time_now)
    Span.setComponentId(exitSpan, nginxComponentId)
    Span.setLayer(exitSpan, Layer.HTTP)

    local upstreamServerName = upstream_name
    if upstreamServerName then
        TC.inject(tracingContext, exitSpan, upstreamServerName, correlation)
    end

    -- Push the data in the context
    local ctx = ngx.ctx
    ctx.tracingContext = tracingContext
    ctx.entrySpan = entrySpan
    ctx.exitSpan = exitSpan
    ctx.is_finished = false
end

-- inject an exit span context and correlation context into carrier
-- since v1.0.0
function Tracer:inject(exitSpan, peer, correlation)
    local ctx = ngx.ctx
    local context = ctx.tracingContext

    if not context.is_noop and exitSpan ~= nil and not ctx.is_finished then
        TC.inject(context, exitSpan, peer, correlation)
    end
end

function Tracer:finish()
    -- Finish the exit span when received the first response package from upstream
    if ngx.ctx.exitSpan ~= nil and not ngx.ctx.is_finished then
        local upstream_status = tonumber(ngx.var.upstream_status)
        if upstream_status then
            Span.tag(ngx.ctx.exitSpan, 'http.status', upstream_status)
        end
        Span.finish(ngx.ctx.exitSpan, ngx.now() * 1000)
        ngx.ctx.exitSpan = nil
        ngx.ctx.is_finished = true
    end
end

function Tracer:prepareForReport()
    if not ngx.ctx.is_finished then
        self.finish()
    end
    local entrySpan = ngx.ctx.entrySpan
    if not entrySpan then
        return
    end

    local ngxstatus = ngx.var.status
    Span.tag(entrySpan, 'http.status', ngxstatus)
    if tonumber(ngxstatus) >= 500 then
        Span.errorOccurred(entrySpan)
    end

    Span.finish(entrySpan, ngx.now() * 1000)

    local ok, segment = TC.drainAfterFinished(ngx.ctx.tracingContext)
    if not ok then
        return
    end

    local segmentJson, err = json.encode(Segment.transform(segment))
    if not segmentJson then
        ngx.log(ngx.ERR, "failed to encode segment: ", err)
        return
    end
    -- ngx.log(ngx.DEBUG, 'segment = ', segmentJson)

    local length, err = metadata_shdict:lpush(Const.segment_queue, segmentJson)
    if not length then
        ngx.log(ngx.ERR, "failed to push segment: ", err)
        return
    end
    -- ngx.log(ngx.DEBUG, 'segment buffer size = ', length)

    Util.tablepool_release()
end

return Tracer
