package db

import (
	"fmt"
	"strings"

	"git.wntrmute.dev/kyle/mc-proxy/internal/config"
)

// Seed populates the database from TOML config data. Only called when the
// database is empty (first run).
func (s *Store) Seed(listeners []config.Listener, fw config.Firewall) error {
	tx, err := s.db.Begin()
	if err != nil {
		return fmt.Errorf("beginning seed transaction: %w", err)
	}
	defer tx.Rollback()

	for _, l := range listeners {
		result, err := tx.Exec(
			"INSERT INTO listeners (addr, proxy_protocol, max_connections) VALUES (?, ?, ?)",
			l.Addr, l.ProxyProtocol, l.MaxConnections,
		)
		if err != nil {
			return fmt.Errorf("seeding listener %q: %w", l.Addr, err)
		}
		listenerID, _ := result.LastInsertId()

		for _, r := range l.Routes {
			mode := r.Mode
			if mode == "" {
				mode = "l4"
			}
			_, err := tx.Exec(
				`INSERT INTO routes (listener_id, hostname, backend, mode, tls_cert, tls_key, backend_tls, send_proxy_protocol)
				 VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
				listenerID, strings.ToLower(r.Hostname), r.Backend,
				mode, r.TLSCert, r.TLSKey, r.BackendTLS, r.SendProxyProtocol,
			)
			if err != nil {
				return fmt.Errorf("seeding route %q on listener %q: %w", r.Hostname, l.Addr, err)
			}
		}
	}

	for _, ip := range fw.BlockedIPs {
		if _, err := tx.Exec("INSERT INTO firewall_rules (type, value) VALUES ('ip', ?)", ip); err != nil {
			return fmt.Errorf("seeding blocked IP %q: %w", ip, err)
		}
	}

	for _, cidr := range fw.BlockedCIDRs {
		if _, err := tx.Exec("INSERT INTO firewall_rules (type, value) VALUES ('cidr', ?)", cidr); err != nil {
			return fmt.Errorf("seeding blocked CIDR %q: %w", cidr, err)
		}
	}

	for _, code := range fw.BlockedCountries {
		if _, err := tx.Exec("INSERT INTO firewall_rules (type, value) VALUES ('country', ?)", strings.ToUpper(code)); err != nil {
			return fmt.Errorf("seeding blocked country %q: %w", code, err)
		}
	}

	return tx.Commit()
}
