-- 
-- 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 Base64 = require('dependencies/base64')

local SegmentRef = {
    -- There is no multiple-threads scenario in the LUA, no only hard coded as CROSS_PROCESS
    type = 'CROSS_PROCESS',
    trace_id,
    segment_id,
    span_id,
    network_address,
    network_address_id = 0,
    entry_service_instance_id = 0,
    parent_service_instance_id = 0,
    entry_endpoint_name,
    entry_endpoint_id = 0,
    parent_endpoint_name,
    parent_endpoint_id = 0,
}

-- Due to nesting relationship inside Segment/Span/TracingContext at the runtime,
-- RefProtocol is created to prepare JSON format serialization.
-- Following SkyWalking official trace protocol v2
-- https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent-v2/trace.proto
local RefProtocol = {
    -- Constant in LUA, no cross-thread
    refType = 'CrossProcess',
    parentTraceSegmentId,
    parentSpanId,
    parentServiceInstanceId,
    networkAddress,
    networkAddressId,
    entryServiceInstanceId,
    entryEndpoint,
    entryEndpointId,
    parentEndpoint,
    parentEndpointId,
}

function SegmentRef:new()
    local o = {}
    setmetatable(o, self)
    self.__index = self

    return o
end

function RefProtocol:new()
    local o = {}
    setmetatable(o, self)
    self.__index = self

    return o
end

-- Deserialize value from the propagated context and initialize the SegmentRef
function SegmentRef:fromSW6Value(value)
    local parts = Util: split(value, '-')
    if #parts ~= 9 then
        return nil
    end

    self.trace_id = Util:formatID(Base64.decode(parts[2]))
    self.segment_id = Util:formatID(Base64.decode(parts[3]))
    self.span_id = tonumber(parts[4])
    self.parent_service_instance_id = tonumber(parts[5])
    self.entry_service_instance_id = tonumber(parts[6])
    local peerStr = Base64.decode(parts[7])
    if string.sub(peerStr, 1, 1) == '#' then
        self.network_address = string.sub(peerStr, 2)
    else
        self.network_address_id = tonumber(peerStr)
    end
    local entryEndpointStr = Base64.decode(parts[8])
    if string.sub(entryEndpointStr, 1, 1) == '#' then
        self.entry_endpoint_name = string.sub(entryEndpointStr, 2)
    else
        self.entry_endpoint_id = tonumber(entryEndpointStr)
    end
    local parentEndpointStr = Base64.decode(parts[9])
    if string.sub(parentEndpointStr, 1, 1) == '#' then
        self.parent_endpoint_name = string.sub(parentEndpointStr, 2)
    else
        self.parent_endpoint_id = tonumber(parentEndpointStr)
    end

    return self
end

-- Return string to represent this ref.
function SegmentRef:serialize()
    local encodedRef = '1'
    encodedRef = encodedRef .. '-' .. Base64.encode(Util:id2String(self.trace_id))
    encodedRef = encodedRef .. '-' .. Base64.encode(Util:id2String(self.segment_id))
    encodedRef = encodedRef .. '-' .. self.span_id
    encodedRef = encodedRef .. '-' .. self.parent_service_instance_id
    encodedRef = encodedRef .. '-' .. self.entry_service_instance_id

    local networkAddress 
    if self.network_address_id ~= 0 then
        networkAddress = self.network_address_id .. ''
    else
        networkAddress = '#' .. self.network_address
    end
    encodedRef = encodedRef .. '-' .. Base64.encode(networkAddress)

    local entryEndpoint
    if self.entry_endpoint_id ~= 0 then
        entryEndpoint = self.entry_endpoint_id .. ''
    else
        entryEndpoint = '#' .. self.entry_endpoint_name
    end
    encodedRef = encodedRef .. '-' .. Base64.encode(entryEndpoint)

    local parentEndpoint
    if self.parent_endpoint_id ~= 0 then
        parentEndpoint = self.parent_endpoint_id .. ''
    else
        parentEndpoint = '#' .. self.parent_endpoint_name
    end
    encodedRef = encodedRef .. '-' .. Base64.encode(parentEndpoint)

    return encodedRef
end

-- Return RefProtocol
function SegmentRef:transform()
    local refBuilder = RefProtocol:new()
    refBuilder.parentTraceSegmentId = {idParts = self.segment_id }
    refBuilder.parentSpanId = self.span_id
    refBuilder.parentServiceInstanceId = self.parent_service_instance_id
    refBuilder.networkAddress = self.network_address
    refBuilder.networkAddressId = self.network_address_id
    refBuilder.entryServiceInstanceId = self.entry_service_instance_id
    refBuilder.entryEndpoint = self.entry_endpoint_name
    refBuilder.entryEndpointId = self.entry_endpoint_id
    refBuilder.parentEndpoint = self.parent_endpoint_name
    refBuilder.parentEndpointId = self.parent_endpoint_id
    return refBuilder
end

return SegmentRef
