package component

import (
	"database/sql"
	"flag"
	"fmt"
	"net/url"
	"os"
	"sync"

	"github.com/cockroachdb/cockroach-go/v2/testserver"
	"github.com/golang-migrate/migrate/v4"
	_ "github.com/golang-migrate/migrate/v4/database/cockroachdb"
	"github.com/golang-migrate/migrate/v4/source"
	_ "github.com/lib/pq"
	"k8s.io/klog/v2"

	"source.monogon.dev/metropolis/cli/pkg/datafile"
)

// CockroachConfig is the common configuration of a components' connection to
// CockroachDB. It's supposed to be instantiated within a Configuration struct
// of a component.
//
// It can be configured by flags (via RegisterFlags) or manually (eg. in tests).
type CockroachConfig struct {
	// Migrations is the go-migrate source of migrations for this database. Usually
	// this can be taken from a go-embedded set of migration files.
	Migrations source.Driver

	// EndpointHost is the host part of the endpoint address of the database server.
	EndpointHost string
	// TLSKeyPath is the filesystem path of the x509 key used to authenticate to the
	// database server.
	TLSKeyPath string
	// TLSKeyPath is the filesystem path of the x509 certificate used to
	// authenticate to the database server.
	TLSCertificatePath string
	// TLSCACertificatePath is the filesystem path of the x509 CA certificate used
	// to verify the database server's certificate.
	TLSCACertificatePath string
	// UserName is the username to be used on the database server.
	UserName string
	// UserName is the database name to be used on the database server.
	DatabaseName string

	// InMemory indicates that an in-memory CockroachDB instance should be used.
	// Data will be lost after the component shuts down.
	InMemory bool

	// mu guards inMemoryInstance.
	mu sync.Mutex
	// inMemoryInstance is populated with a CockroachDB test server handle when
	// InMemory is set and Connect()/MigrateUp() is called.
	inMemoryInstance testserver.TestServer
}

// RegisterFlags registers the connection configuration to be provided by flags.
// This must be called exactly once before then calling flags.Parse().
func (c *CockroachConfig) RegisterFlags(prefix string) {
	flag.StringVar(&c.EndpointHost, prefix+"_endpoint_host", "", "Host of CockroachDB endpoint for "+prefix)
	flag.StringVar(&c.TLSKeyPath, prefix+"_tls_key_path", "", "Path to CockroachDB TLS client key for "+prefix)
	flag.StringVar(&c.TLSCertificatePath, prefix+"_tls_certificate_path", "", "Path to CockroachDB TLS client certificate for "+prefix)
	flag.StringVar(&c.TLSCACertificatePath, prefix+"_tls_ca_certificate_path", "", "Path to CockroachDB CA certificate for "+prefix)
	flag.StringVar(&c.UserName, prefix+"_user_name", prefix, "CockroachDB user name for "+prefix)
	flag.StringVar(&c.DatabaseName, prefix+"_database_name", prefix, "CockroachDB database name for "+prefix)
	flag.BoolVar(&c.InMemory, prefix+"_eat_my_data", false, "Use in-memory CockroachDB for "+prefix+". Warning: Data will be lost at process shutdown!")
}

// startInMemory starts an in-memory cockroachdb server as a subprocess, and
// returns a DSN that connects to the newly created database.
func (c *CockroachConfig) startInMemory(scheme string) string {
	c.mu.Lock()
	defer c.mu.Unlock()

	klog.Warningf("STARTING IN-MEMORY COCKROACHDB FOR TESTS")
	klog.Warningf("ALL DATA WILL BE LOST AFTER SERVER SHUTDOWN!")

	if c.inMemoryInstance == nil {
		opts := []testserver.TestServerOpt{
			testserver.SecureOpt(),
		}
		if path, err := datafile.ResolveRunfile("external/cockroach/cockroach"); err == nil {
			opts = append(opts, testserver.CockroachBinaryPathOpt(path))
		} else {
			if os.Getenv("TEST_TMPDIR") != "" {
				klog.Exitf("In test which requires in-memory cockroachdb, but @cockroach//:cockroach missing as a dependency. Failing.")
			}
			klog.Warningf("CockroachDB in-memory database requested, but not available as a build dependency. Trying to download it...")
		}

		inst, err := testserver.NewTestServer(opts...)
		if err != nil {
			klog.Exitf("Failed to create crdb test server: %v", err)
		}
		c.inMemoryInstance = inst
	}

	u := *c.inMemoryInstance.PGURL()
	u.Scheme = scheme
	return u.String()
}

// buildDSN returns a DSN to the configured database connection with a given DSN
// scheme. The scheme will usually be 'postgres' or 'cockroach', depending on
// whether it's used for lib/pq or for golang-migrate.
func (c *CockroachConfig) buildDSN(scheme string) string {
	if c.InMemory {
		return c.startInMemory(scheme)
	}

	query := make(url.Values)
	query.Set("sslmode", "verify-full")
	query.Set("sslcert", c.TLSCertificatePath)
	query.Set("sslkey", c.TLSKeyPath)
	query.Set("sslrootcert", c.TLSCACertificatePath)
	u := url.URL{
		Scheme:   scheme,
		User:     url.User(c.UserName),
		Host:     c.EndpointHost,
		Path:     c.DatabaseName,
		RawQuery: query.Encode(),
	}
	return u.String()
}

// Connect returns a working *sql.DB handle to the database described by this
// CockroachConfig.
func (d *CockroachConfig) Connect() (*sql.DB, error) {
	dsn := d.buildDSN("postgres")
	klog.Infof("Connecting to %s...", dsn)
	return sql.Open("postgres", d.buildDSN("postgres"))
}

// MigrateUp performs all possible migrations upwards for the database described
// by this CockroachConfig.
func (d *CockroachConfig) MigrateUp() error {
	dsn := d.buildDSN("cockroachdb")
	klog.Infof("Running migrations on %s...", dsn)
	m, err := migrate.NewWithSourceInstance("iofs", d.Migrations, dsn)
	if err != nil {
		return err
	}
	return m.Up()
}

// MigrateDownDangerDanger removes all data from the database by performing a
// full migration down.
//
// Let me reiterate: this function, by design, DESTROYS YOUR DATA.
//
// Obviously, this is a dangerous method. Thus, to prevent accidental nuking of
// production data, we currently only allow this to be performed on InMemory
// databases.
func (d *CockroachConfig) MigrateDownDangerDanger() error {
	if !d.InMemory {
		return fmt.Errorf("refusing to migrate down a non-in-memory database")
	}
	// Sneaky extra check to make sure the caller didn't just set InMemory after
	// connecting to an external database. We really need to be safe here.
	if d.inMemoryInstance == nil {
		return fmt.Errorf("no really, this cannot be run on non-in-memory databases")
	}
	dsn := d.buildDSN("cockroachdb")
	klog.Infof("Running migrations on %s...", dsn)
	m, err := migrate.NewWithSourceInstance("iofs", d.Migrations, dsn)
	if err != nil {
		return err
	}
	// Final sneaky check, make sure the remote schema version is our maximum locally
	// supported version.
	v, _, err := m.Version()
	if err != nil {
		return fmt.Errorf("could not retrieve remote version: %w", err)
	}
	if v2, err := d.Migrations.Next(v); !os.IsNotExist(err) {
		return fmt.Errorf("remote running version %d, but we know %d which is newer", v, v2)
	}
	return m.Down()
}
