// Licensed to 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. Apache Software Foundation (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.

package tracing

import (
	"github.com/apache/skywalking-go/plugins/core/operator"
)

var (
	errParameter = operator.NewError("parameter are nil")
)

// CreateEntrySpan creates a new entry span.
// operationName is the name of the span.
// extractor is the extractor to extract the context from the carrier.
// opts is the options to create the span.
func CreateEntrySpan(operationName string, extractor Extractor, opts ...SpanOption) (s Span, err error) {
	if operationName == "" || extractor == nil {
		return nil, errParameter
	}
	op := operator.GetOperator()
	if op == nil {
		return &NoopSpan{}, nil
	}
	span, err := op.Tracing().(operator.TracingOperator).CreateEntrySpan(operationName, extractorWrapper(extractor), copyOptsAsInterface(opts)...)
	if err != nil {
		return nil, err
	}
	return newSpanAdapter(span.(AdaptSpan)), nil
}

// CreateLocalSpan creates a new local span.
// operationName is the name of the span.
// opts is the options to create the span.
func CreateLocalSpan(operationName string, opts ...SpanOption) (s Span, err error) {
	if operationName == "" {
		return nil, errParameter
	}
	op := operator.GetOperator()
	if op == nil {
		return &NoopSpan{}, nil
	}
	span, err := op.Tracing().(operator.TracingOperator).CreateLocalSpan(operationName, copyOptsAsInterface(opts)...)
	if err != nil {
		return nil, err
	}
	return newSpanAdapter(span.(AdaptSpan)), nil
}

// CreateExitSpan creates a new exit span.
// operationName is the name of the span.
// peer is the peer address of the span.
// injector is the injector to inject the context into the carrier.
// opts is the options to create the span.
func CreateExitSpan(operationName, peer string, injector Injector, opts ...SpanOption) (s Span, err error) {
	if operationName == "" || peer == "" || injector == nil {
		return nil, errParameter
	}
	op := operator.GetOperator()
	if op == nil {
		return &NoopSpan{}, nil
	}
	span, err := op.Tracing().(operator.TracingOperator).CreateExitSpan(operationName, peer, injectorWrapper(injector), copyOptsAsInterface(opts)...)
	if err != nil {
		return nil, err
	}
	return newSpanAdapter(span.(AdaptSpan)), nil
}

// ActiveSpan returns the current active span, it can be got the current span in the current goroutine.
// If the current goroutine is not in the context of the span, it will return nil.
// If get the span from other goroutine, it can only get information but cannot be operated.
func ActiveSpan() Span {
	op := operator.GetOperator()
	if op == nil {
		return nil
	}
	if span, ok := op.Tracing().(operator.TracingOperator).ActiveSpan().(AdaptSpan); ok {
		return newSpanAdapter(span)
	}
	return nil
}

// GetRuntimeContextValue returns the value of the key in the runtime context, which is current goroutine.
// The value can also read from the goroutine which is created by the current goroutine
func GetRuntimeContextValue(key string) interface{} {
	op := operator.GetOperator()
	if op == nil {
		return nil
	}
	return op.Tracing().(operator.TracingOperator).GetRuntimeContextValue(key)
}

// SetRuntimeContextValue sets the value of the key in the runtime context.
func SetRuntimeContextValue(key string, val interface{}) {
	op := operator.GetOperator()
	if op != nil {
		op.Tracing().(operator.TracingOperator).SetRuntimeContextValue(key, val)
	}
}

// DebugStack returns the stack of the current goroutine, for getting details when plugin broken.
func DebugStack() []byte {
	op := operator.GetOperator()
	if op == nil {
		return nil
	}
	return op.DebugStack()
}

func copyOptsAsInterface(opts []SpanOption) []interface{} {
	optsVal := make([]interface{}, len(opts))
	for i := range opts {
		optsVal[i] = opts[i]
	}
	return optsVal
}

type extractorWrapperImpl struct {
	extractor Extractor
}

func (e *extractorWrapperImpl) Fun() func(headerKey string) (string, error) {
	return e.extractor
}

func extractorWrapper(extractor Extractor) *extractorWrapperImpl {
	return &extractorWrapperImpl{extractor: extractor}
}

type injectorWrapperImpl struct {
	injector Injector
}

func (i *injectorWrapperImpl) Fun() func(headerKey, headerValue string) error {
	return i.injector
}

func injectorWrapper(injector Injector) *injectorWrapperImpl {
	return &injectorWrapperImpl{injector: injector}
}

var noopSpanTraceOrSegmentID = "N/A"

type NoopSpan struct {
}

func (n *NoopSpan) TraceID() string {
	return noopSpanTraceOrSegmentID
}

func (n *NoopSpan) TraceSegmentID() string {
	return noopSpanTraceOrSegmentID
}

func (n *NoopSpan) SpanID() int32 {
	return -1
}

func (n *NoopSpan) SetOperationName(string) {
}
func (n *NoopSpan) SetPeer(string) {
}
func (n *NoopSpan) SetSpanLayer(SpanLayer) {
}
func (n *NoopSpan) SetComponent(int32) {
}
func (n *NoopSpan) Tag(Tag, string) {
}
func (n *NoopSpan) Log(...string) {
}
func (n *NoopSpan) Error(...string) {
}
func (n *NoopSpan) End() {
}
