/*
==================================================================================
  Copyright (c) 2019 AT&T Intellectual Property.
  Copyright (c) 2019 Nokia

   Licensed 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 control

import (
	"gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
	"gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/xapptweaks"
	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
	"strconv"
	"sync"
	"time"
)

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
type TransactionIf interface {
	String() string
	Release()
	SendEvent(interface{}, time.Duration) (bool, bool)
	WaitEvent(time.Duration) (interface{}, bool)
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------

type Transaction struct {
	mutex     sync.Mutex       //
	Seq       uint64           //transaction sequence
	tracker   *Tracker         //tracker instance
	Meid      *xapp.RMRMeid    //meid transaction related
	Mtype     int              //Encoded message type to be send
	Payload   *e2ap.PackedData //Encoded message to be send
	EventChan chan interface{}
}

func (t *Transaction) String() string {
	return "trans(" + strconv.FormatUint(uint64(t.Seq), 10) + "/" + (&xapptweaks.RMRMeid{t.Meid}).String() + ")"
}

func (t *Transaction) SendEvent(event interface{}, waittime time.Duration) (bool, bool) {
	if waittime > 0 {
		select {
		case t.EventChan <- event:
			return true, false
		case <-time.After(waittime):
			return false, true
		}
		return false, false
	}
	t.EventChan <- event
	return true, false
}

func (t *Transaction) WaitEvent(waittime time.Duration) (interface{}, bool) {
	if waittime > 0 {
		select {
		case event := <-t.EventChan:
			return event, false
		case <-time.After(waittime):
			return nil, true
		}
	}
	event := <-t.EventChan
	return event, false
}

func (t *Transaction) GetMtype() int {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	return t.Mtype
}

func (t *Transaction) GetMeid() *xapp.RMRMeid {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	if t.Meid != nil {
		return t.Meid
	}
	return nil
}

func (t *Transaction) GetPayload() *e2ap.PackedData {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	return t.Payload
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
type TransactionSubs struct {
	Transaction //
}

func (t *TransactionSubs) String() string {
	return "transsubs(" + t.Transaction.String() + ")"
}

func (t *TransactionSubs) Release() {
	t.mutex.Lock()
	xapp.Logger.Debug("RELEASE %s", t.String())
	t.tracker = nil
	t.mutex.Unlock()
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
type TransactionXappKey struct {
	RmrEndpoint
	Xid string // xapp xid in req
}

func (key *TransactionXappKey) String() string {
	return "transkey(" + key.RmrEndpoint.String() + "/" + key.Xid + ")"
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
type TransactionXapp struct {
	Transaction
	XappKey *TransactionXappKey
	SubId   uint32
}

func (t *TransactionXapp) String() string {
	var transkey string = "transkey(N/A)"
	if t.XappKey != nil {
		transkey = t.XappKey.String()
	}
	return "transxapp(" + t.Transaction.String() + "/" + transkey + "/" + strconv.FormatUint(uint64(t.SubId), 10) + ")"
}

func (t *TransactionXapp) GetEndpoint() *RmrEndpoint {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	if t.XappKey != nil {
		return &t.XappKey.RmrEndpoint
	}
	return nil
}

func (t *TransactionXapp) GetXid() string {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	if t.XappKey != nil {
		return t.XappKey.Xid
	}
	return ""
}

func (t *TransactionXapp) GetSrc() string {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	if t.XappKey != nil {
		return t.XappKey.RmrEndpoint.String()
	}
	return ""
}

func (t *TransactionXapp) GetSubId() uint32 {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	return t.SubId
}

func (t *TransactionXapp) Release() {
	t.mutex.Lock()
	xapp.Logger.Debug("RELEASE %s", t.String())
	tracker := t.tracker
	xappkey := t.XappKey
	t.tracker = nil
	t.mutex.Unlock()

	if tracker != nil && xappkey != nil {
		tracker.UnTrackTransaction(*xappkey)
	}
}
