package postgres

import (
	"context"
	"database/sql"

	"code.justin.tv/eventbus/controlplane/internal/db"
)

const (
	featureFlagQuery           = "SELECT * FROM feature_flags WHERE name = $1"
	selectAllFeatureFlagsQuery = "SELECT * FROM feature_flags ORDER BY name"
	createFeatureFlagQuery     = "INSERT INTO feature_flags (name, enabled) values (:name, :enabled) RETURNING id"
	deleteFeatureFlagQuery     = "DELETE FROM feature_flags WHERE name=$1"
	toggleFeatureFlagQuery     = "UPDATE feature_flags SET enabled = $2 WHERE name = $1"
)

func (pg *PostgresDB) FeatureFlagByName(ctx context.Context, name string) (*db.FeatureFlag, error) {
	var ff db.FeatureFlag
	err := pg.reader.GetContext(ctx, &ff, featureFlagQuery, name)
	if err == sql.ErrNoRows {
		return nil, db.ErrResourceNotFound
	}
	return &ff, err
}

func (pg *PostgresDB) FeatureFlags(ctx context.Context) ([]*db.FeatureFlag, error) {
	var featureFlags []*db.FeatureFlag
	err := pg.reader.SelectContext(ctx, &featureFlags, selectAllFeatureFlagsQuery)
	return featureFlags, err
}

func (pg *PostgresDB) FeatureFlagCreate(ctx context.Context, ff *db.FeatureFlag) (int, error) {
	var id int
	namedQuery, err := pg.writer.PrepareNamedContext(ctx, createFeatureFlagQuery)
	if err != nil {
		return -1, err
	}

	err = namedQuery.QueryRowxContext(ctx, ff).Scan(&id)
	return id, err
}

func (pg *PostgresDB) FeatureFlagDelete(ctx context.Context, name string) error {
	deleteRes, err := pg.writer.ExecContext(ctx, deleteFeatureFlagQuery, name)
	if err != nil {
		return err
	}
	numRowsAffected, err := deleteRes.RowsAffected()
	if err != nil {
		return err
	}
	if numRowsAffected == 0 {
		return db.ErrResourceNotFound
	}
	return nil
}

func (pg *PostgresDB) FeatureFlagEnable(ctx context.Context, name string) error {
	return pg.featureFlagToggle(ctx, name, true)
}

func (pg *PostgresDB) FeatureFlagDisable(ctx context.Context, name string) error {
	return pg.featureFlagToggle(ctx, name, false)
}

func (pg *PostgresDB) featureFlagToggle(ctx context.Context, name string, enabled bool) error {
	toggleResp, err := pg.writer.ExecContext(ctx, toggleFeatureFlagQuery, name, enabled)
	if err != nil {
		return err
	}
	numRowsAffected, err := toggleResp.RowsAffected()
	if err != nil {
		return err
	}
	if numRowsAffected == 0 {
		return db.ErrResourceNotFound
	}
	return nil
}
