package db

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

	"tangled.org/core/knotmirror/models"
)

func UpsertHost(ctx context.Context, e *sql.DB, host *models.Host) error {
	if _, err := e.ExecContext(ctx,
		`insert into hosts (hostname, no_ssl, status, last_tid)
		values ($1, $2, $3, $4)
		on conflict(hostname) do update set
			no_ssl   = excluded.no_ssl,
			status   = excluded.status,
			last_tid = excluded.last_tid
		`,
		host.Hostname,
		host.NoSSL,
		host.Status,
		host.LastTid,
	); err != nil {
		return fmt.Errorf("upserting host: %w", err)
	}
	return nil
}

func GetHost(ctx context.Context, e *sql.DB, hostname string) (*models.Host, error) {
	var host models.Host
	if err := e.QueryRowContext(ctx,
		`select hostname, no_ssl, status, last_tid
		from hosts where hostname = $1`,
		hostname,
	).Scan(
		&host.Hostname,
		&host.NoSSL,
		&host.Status,
		&host.LastTid,
	); err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, nil
		}
		return nil, err
	}
	return &host, nil
}

func ListHosts(ctx context.Context, e *sql.DB, status models.HostStatus) ([]models.Host, error) {
	rows, err := e.QueryContext(ctx,
		`select hostname, no_ssl, status, last_tid
		from hosts
		where status = $1`,
		status,
	)
	if err != nil {
		return nil, fmt.Errorf("querying hosts: %w", err)
	}
	defer rows.Close()

	var hosts []models.Host
	for rows.Next() {
		var host models.Host
		if err := rows.Scan(
			&host.Hostname,
			&host.NoSSL,
			&host.Status,
			&host.LastTid,
		); err != nil {
			return nil, fmt.Errorf("scanning row: %w", err)
		}
		hosts = append(hosts, host)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("scanning rows: %w ", err)
	}
	return hosts, nil
}
