package txpool

import (
	"sync/atomic"

	"github.com/0xPolygon/polygon-edge/types"
)

/* QUERY methods */
// Used to query the pool for specific state info.

// GetNonce returns the next nonce for the account
//
// -> Returns the value from the TxPool if the account is initialized in-memory
//
// -> Returns the value from the world state otherwise
func (p *TxPool) GetNonce(addr types.Address) uint64 {
	account := p.accounts.get(addr)
	if account == nil {
		stateRoot := p.store.Header().StateRoot
		stateNonce := p.store.GetNonce(stateRoot, addr)

		return stateNonce
	}

	return account.getNonce()
}

// GetCapacity returns the current number of slots
// occupied in the pool as well as the max limit
func (p *TxPool) GetCapacity() (uint64, uint64) {
	return p.gauge.read(), p.gauge.max
}

// GetPendingTx returns the transaction by hash in the TxPool (pending txn) [Thread-safe]
func (p *TxPool) GetPendingTx(txHash types.Hash) (*types.Transaction, bool) {
	tx, ok := p.index.get(txHash)
	if !ok {
		return nil, false
	}

	return tx, true
}

// GetTxs gets pending and queued transactions
func (p *TxPool) GetTxs(inclQueued bool) (
	allPromoted, allEnqueued map[types.Address][]*types.Transaction,
) {
	return p.accounts.allTxs(inclQueued)
}

// GetBaseFee returns current base fee
func (p *TxPool) GetBaseFee() uint64 {
	return atomic.LoadUint64(&p.baseFee)
}

// SetBaseFee calculates base fee from the (current) header and sets value into baseFee field
func (p *TxPool) SetBaseFee(header *types.Header) {
	atomic.StoreUint64(&p.baseFee, p.store.CalculateBaseFee(header))
}
