/*
 * Copyright 2018-present Open Networking Foundation

 * 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 model

import (
	"sync"
)

// Profiling is used to store performance details collected at runtime
type Profiling struct {
	sync.RWMutex
	DatabaseRetrieveTime  float64
	DatabaseRetrieveCount int
	InMemoryModelTime     float64
	InMemoryModelCount    int
	InMemoryProcessTime   float64
	DatabaseStoreTime     float64
	InMemoryLockTime      float64
	InMemoryLockCount     int
}

var profilingInstance *Profiling
var profilingOnce sync.Once

// GetProfiling returns a singleton instance of the Profiling structure
func GetProfiling() *Profiling {
	profilingOnce.Do(func() {
		profilingInstance = &Profiling{}
	})
	return profilingInstance
}

// AddToDatabaseRetrieveTime appends a time period to retrieve data from the database
func (p *Profiling) AddToDatabaseRetrieveTime(period float64) {
	p.Lock()
	defer p.Unlock()

	p.DatabaseRetrieveTime += period
	p.DatabaseRetrieveCount++
}

// AddToInMemoryModelTime appends a time period to construct/deconstruct data in memory
func (p *Profiling) AddToInMemoryModelTime(period float64) {
	p.Lock()
	defer p.Unlock()

	p.InMemoryModelTime += period
	p.InMemoryModelCount++
}

// AddToInMemoryProcessTime appends a time period to process data
func (p *Profiling) AddToInMemoryProcessTime(period float64) {
	p.Lock()
	defer p.Unlock()

	p.InMemoryProcessTime += period
}

// AddToDatabaseStoreTime appends a time period to store data in the database
func (p *Profiling) AddToDatabaseStoreTime(period float64) {
	p.Lock()
	defer p.Unlock()

	p.DatabaseStoreTime += period
}

// AddToInMemoryLockTime appends a time period when a code block was locked
func (p *Profiling) AddToInMemoryLockTime(period float64) {
	p.Lock()
	defer p.Unlock()

	p.InMemoryLockTime += period
	p.InMemoryLockCount++
}

// Reset initializes the profile counters
func (p *Profiling) Reset() {
	p.Lock()
	defer p.Unlock()

	p.DatabaseRetrieveTime = 0
	p.DatabaseRetrieveCount = 0
	p.InMemoryModelTime = 0
	p.InMemoryModelCount = 0
	p.InMemoryProcessTime = 0
	p.DatabaseStoreTime = 0
	p.InMemoryLockTime = 0
	p.InMemoryLockCount = 0
}

// Report will provide the current profile counter status
func (p *Profiling) Report() {
	p.Lock()
	defer p.Unlock()

	logger.Infof("[ Profiling Report ]")
	logger.Infof("Database Retrieval : %f", p.DatabaseRetrieveTime)
	logger.Infof("Database Retrieval Count : %d", p.DatabaseRetrieveCount)
	logger.Infof("Avg Database Retrieval : %f", p.DatabaseRetrieveTime/float64(p.DatabaseRetrieveCount))
	logger.Infof("In-Memory Modeling : %f", p.InMemoryModelTime)
	logger.Infof("In-Memory Modeling Count: %d", p.InMemoryModelCount)
	logger.Infof("Avg In-Memory Modeling : %f", p.InMemoryModelTime/float64(p.InMemoryModelCount))
	logger.Infof("In-Memory Locking : %f", p.InMemoryLockTime)
	logger.Infof("In-Memory Locking Count: %d", p.InMemoryLockCount)
	logger.Infof("Avg In-Memory Locking : %f", p.InMemoryLockTime/float64(p.InMemoryLockCount))

}
