-- 
-- 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 Util = require('util')
local Span = require('span')
local Segment = require('segment')

local TracingContext = {
    trace_id,
    segment_id,
    service_id,
    service_inst_id,

    is_noop = false,

    internal,
}

-------------- Internal Object-------------
-- Internal Object hosts the methods for SkyWalking LUA internal APIs only.
local Internal = {
    self_generated_trace_id,
    -- span id starts from 0
    span_id_seq,
    -- Owner means the Context instance holding this Internal object.
    owner,
    -- The first created span.
    first_span,
    -- The first ref injected in this context
    first_ref,
    -- Created span and still active
    active_spans,
    active_count,
    -- Finished spans
    finished_spans,
}

function TracingContext:new(serviceId, serviceInstID)
    local o = {}
    setmetatable(o, self)
    self.__index = self

    if serviceInstID == nil then
        return TracingContext:newNoOP()
    end

    o.trace_id = Util:newID()
    o.segment_id = o.trace_id
    o.service_id = serviceId
    o.service_inst_id = serviceInstID
    o.internal = Internal:new()
    o.internal.owner = o
    return o
end

function TracingContext:newNoOP()
    local o = {}
    setmetatable(o, self)
    self.__index = self

    o.is_noop = true
    return o
end

-- Delegate to Span:createEntrySpan
-- @param contextCarrier could be nil if there is no downstream propagated context
function TracingContext:createEntrySpan(operationName, parent, contextCarrier)
    if self.is_noop then
        return Span:newNoOP()
    end

    return Span:createEntrySpan(operationName, self, parent, contextCarrier)
end

-- Delegate to Span:createExitSpan
-- @param contextCarrier could be nil if don't need to inject any context to propagate
function TracingContext:createExitSpan(operationName, parent, peer, contextCarrier)
    if self.is_noop then
        return Span:newNoOP()
    end

    return Span:createExitSpan(operationName, self, parent, peer, contextCarrier)
end

-- After all active spans finished, this segment will be treated as finished status.
-- Notice, it is different with Java agent, a finished context is still able to recreate new span, and be checked as finished again.
-- This gives the end user more flexibility. Unless it is a real reasonable case, don't call #drainAfterFinished multiple times.
-- 
-- Return (boolean isSegmentFinished, Segment segment). 
-- Segment has value only when the isSegmentFinished is true
-- if isSegmentFinished == false, SpanList = nil
function TracingContext:drainAfterFinished()
    if self.is_noop then
        return true, Segment:new()
    end

    if self.internal.active_count ~= 0 then
        return false, nil
    else
        local segment = Segment:new()
        segment.trace_id = self.trace_id
        segment.segment_id = self.segment_id
        segment.service_id = self.service_id
        segment.service_inst_id = self.service_inst_id
        segment.spans = self.internal.finished_spans
        return true, segment
    end
end

-------------- Internal Object-------------
-- Internal Object hosts the methods for SkyWalking LUA internal APIs only.

-- Create an internal instance
function Internal:new()
    local o = {}
    setmetatable(o, self)
    self.__index = self

    o.self_generated_trace_id = true
    o.span_id_seq = 0
    o.active_spans = {}
    o.active_count = 0
    o.finished_spans = {}

    return o
end

-- add the segment ref if this is the first ref of this context
function Internal:addRefIfFirst(ref)
    if self.self_generated_trace_id == true then
        self.self_generated_trace_id = false
        self.owner.trace_id = ref.trace_id
        self.first_ref = ref
    end
end

function Internal:hasRef()
    return first_ref ~= nil
end

function Internal:getFirstRef()
    return first_ref
end

function Internal:addActive(span)
    if self.first_span == nil then
        self.first_span = span
    end

    -- span id starts at 0, to fit LUA, we need to plus one.    
    self.active_spans[span.span_id + 1] = span
    self.active_count = self.active_count + 1
    return self.owner
end

function Internal:finishSpan(span)
    -- span id starts at 0, to fit LUA, we need to plus one.
    self.active_spans[span.span_id + 1] = nil
    self.active_count = self.active_count - 1
    self.finished_spans[#self.finished_spans + 1] = span

    return self.owner
end

-- Generate the next span ID.
function Internal:nextSpanID()
    local nextSpanId = self.span_id_seq
    self.span_id_seq = self.span_id_seq + 1;
    return nextSpanId
end
---------------------------------------------

return TracingContext