// Package sql implements the blockchain.Store interface using SQL database backends.
// It provides concrete SQL-based implementations for all blockchain operations
// defined in the interface, with support for different SQL engines.
//
// This file implements the GetBlockIsMined method, which determines whether a specific
// block was mined by the local node. This functionality is important for mining operations,
// block propagation decisions, and analytics about the node's contribution to the network.
// The implementation performs a simple SQL query to check the mined_set flag in the blocks
// table, which is set to true when a block is created by the local mining process rather
// than received from the network. This distinction is valuable for mining pools, solo miners,
// and nodes tracking their own contributions to blockchain consensus.
package sql

import (
	"context"
	"database/sql"

	"github.com/bsv-blockchain/go-bt/v2/chainhash"
	"github.com/bsv-blockchain/teranode/errors"
	"github.com/bsv-blockchain/teranode/util/tracing"
)

// GetBlockIsMined checks whether a specific block was mined by the local node.
// This implements the blockchain.Store.GetBlockIsMined interface method.
//
// The method determines if a block was created by the local mining process rather than
// received from the network. This distinction is important for mining operations, block
// propagation decisions, and analytics about the node's contribution to the blockchain.
// In Teranode's high-throughput architecture, tracking locally mined blocks helps with
// performance analysis, mining efficiency monitoring, and network contribution metrics.
//
// The implementation performs a simple SQL query to check the mined_set flag in the blocks
// table, which is set to true when a block is stored with the mined flag during the
// StoreBlock operation. This flag is typically set for blocks generated by the local mining
// process or mining pool.
//
// Parameters:
//   - ctx: Context for the database operation, allowing for cancellation and timeouts
//   - blockHash: The hash of the block to check for mining status
//
// Returns:
//   - bool: True if the block was mined by the local node, false otherwise
//   - error: Any error encountered during the check, specifically:
//   - BlockNotFoundError if the specified block doesn't exist in the database
//   - StorageError for database errors or processing failures
func (s *SQL) GetBlockIsMined(ctx context.Context, blockHash *chainhash.Hash) (bool, error) {
	ctx, _, deferFn := tracing.Tracer("blockchain").Start(ctx, "sql:GetBlockIsMined")
	defer deferFn()

	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	q := `
		SELECT
		  b.mined_set
		FROM blocks b
		WHERE hash = $1
	`

	var isMined bool

	err := s.db.QueryRowContext(ctx, q, blockHash[:]).Scan(&isMined)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return false, errors.NewBlockNotFoundError("[GetBlockIsMined][%s] block not found", blockHash.String())
		}

		return false, err
	}

	return isMined, nil
}
