//go:build linux && cgo && !agent

// Code generated by generate-database from the incus project - DO NOT EDIT.

package cluster

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"strings"
)

var networkConfigObjects = RegisterStmt(`
SELECT networks_config.id, networks_config.network_id, coalesce(networks_config.node_id, 0), networks_config.key, networks_config.value
  FROM networks_config
  ORDER BY networks_config.id
`)

var networkConfigObjectsByNodeID = RegisterStmt(`
SELECT networks_config.id, networks_config.network_id, coalesce(networks_config.node_id, 0), networks_config.key, networks_config.value
  FROM networks_config
  WHERE ( coalesce(networks_config.node_id, 0) = ? )
  ORDER BY networks_config.id
`)

var networkConfigObjectsByNodeIDAndNetworkID = RegisterStmt(`
SELECT networks_config.id, networks_config.network_id, coalesce(networks_config.node_id, 0), networks_config.key, networks_config.value
  FROM networks_config
  WHERE ( coalesce(networks_config.node_id, 0) = ? AND networks_config.network_id = ? )
  ORDER BY networks_config.id
`)

// networkConfigColumns returns a string of column names to be used with a SELECT statement for the entity.
// Use this function when building statements to retrieve database entries matching the NetworkConfig entity.
func networkConfigColumns() string {
	return "networks_config.id, networks_config.network_id, coalesce(networks_config.node_id, 0), networks_config.key, networks_config.value"
}

// getNetworkConfig can be used to run handwritten sql.Stmts to return a slice of objects.
func getNetworkConfig(ctx context.Context, stmt *sql.Stmt, args ...any) ([]NetworkConfig, error) {
	objects := make([]NetworkConfig, 0)

	dest := func(scan func(dest ...any) error) error {
		n := NetworkConfig{}
		err := scan(&n.ID, &n.NetworkID, &n.NodeID, &n.Key, &n.Value)
		if err != nil {
			return err
		}

		objects = append(objects, n)

		return nil
	}

	err := selectObjects(ctx, stmt, dest, args...)
	if err != nil {
		return nil, fmt.Errorf("Failed to fetch from \"networks_config\" table: %w", err)
	}

	return objects, nil
}

// getNetworkConfigRaw can be used to run handwritten query strings to return a slice of objects.
func getNetworkConfigRaw(ctx context.Context, db dbtx, sql string, args ...any) ([]NetworkConfig, error) {
	objects := make([]NetworkConfig, 0)

	dest := func(scan func(dest ...any) error) error {
		n := NetworkConfig{}
		err := scan(&n.ID, &n.NetworkID, &n.NodeID, &n.Key, &n.Value)
		if err != nil {
			return err
		}

		objects = append(objects, n)

		return nil
	}

	err := scan(ctx, db, sql, dest, args...)
	if err != nil {
		return nil, fmt.Errorf("Failed to fetch from \"networks_config\" table: %w", err)
	}

	return objects, nil
}

// GetNetworkConfig returns all available network_config.
// generator: network_config GetMany
func GetNetworkConfig(ctx context.Context, db dbtx, filters ...NetworkConfigFilter) (_ []NetworkConfig, _err error) {
	defer func() {
		_err = mapErr(_err, "Network_config")
	}()

	var err error

	// Result slice.
	objects := make([]NetworkConfig, 0)

	// Pick the prepared statement and arguments to use based on active criteria.
	var sqlStmt *sql.Stmt
	args := []any{}
	queryParts := [2]string{}

	if len(filters) == 0 {
		sqlStmt, err = Stmt(db, networkConfigObjects)
		if err != nil {
			return nil, fmt.Errorf("Failed to get \"networkConfigObjects\" prepared statement: %w", err)
		}
	}

	for i, filter := range filters {
		if filter.NodeID != nil && filter.NetworkID != nil {
			args = append(args, []any{filter.NodeID, filter.NetworkID}...)
			if len(filters) == 1 {
				sqlStmt, err = Stmt(db, networkConfigObjectsByNodeIDAndNetworkID)
				if err != nil {
					return nil, fmt.Errorf("Failed to get \"networkConfigObjectsByNodeIDAndNetworkID\" prepared statement: %w", err)
				}

				break
			}

			query, err := StmtString(networkConfigObjectsByNodeIDAndNetworkID)
			if err != nil {
				return nil, fmt.Errorf("Failed to get \"networkConfigObjects\" prepared statement: %w", err)
			}

			parts := strings.SplitN(query, "ORDER BY", 2)
			if i == 0 {
				copy(queryParts[:], parts)
				continue
			}

			_, where, _ := strings.Cut(parts[0], "WHERE")
			queryParts[0] += "OR" + where
		} else if filter.NodeID != nil && filter.NetworkID == nil {
			args = append(args, []any{filter.NodeID}...)
			if len(filters) == 1 {
				sqlStmt, err = Stmt(db, networkConfigObjectsByNodeID)
				if err != nil {
					return nil, fmt.Errorf("Failed to get \"networkConfigObjectsByNodeID\" prepared statement: %w", err)
				}

				break
			}

			query, err := StmtString(networkConfigObjectsByNodeID)
			if err != nil {
				return nil, fmt.Errorf("Failed to get \"networkConfigObjects\" prepared statement: %w", err)
			}

			parts := strings.SplitN(query, "ORDER BY", 2)
			if i == 0 {
				copy(queryParts[:], parts)
				continue
			}

			_, where, _ := strings.Cut(parts[0], "WHERE")
			queryParts[0] += "OR" + where
		} else if filter.NetworkID == nil && filter.NodeID == nil {
			return nil, fmt.Errorf("Cannot filter on empty NetworkConfigFilter")
		} else {
			return nil, errors.New("No statement exists for the given Filter")
		}
	}

	// Select.
	if sqlStmt != nil {
		objects, err = getNetworkConfig(ctx, sqlStmt, args...)
	} else {
		queryStr := strings.Join(queryParts[:], "ORDER BY")
		objects, err = getNetworkConfigRaw(ctx, db, queryStr, args...)
	}

	if err != nil {
		return nil, fmt.Errorf("Failed to fetch from \"networks_config\" table: %w", err)
	}

	return objects, nil
}
