package central

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

	"cloud.google.com/go/bigquery"
	"github.com/jackc/pgx/v5"
	"github.com/pingcap/errors"
	"github.com/snowflakedb/gosnowflake"
	"google.golang.org/api/option"
)

func checkSnowflakeAccess(ctx context.Context, model *connectionModel) error {
	sfConfig := gosnowflake.Config{
		Account:  model.Url,
		User:     model.User,
		Password: model.Password,
	}
	dsn, err := gosnowflake.DSN(&sfConfig)
	if err != nil {
		return err
	}
	db, err := sql.Open("snowflake", dsn)
	if err != nil {
		return err
	}
	defer db.Close()
	if err = db.PingContext(ctx); err != nil {
		return err
	}
	return nil
}

func checkRedshiftAccess(ctx context.Context, model *connectionModel) error {
	connStr := fmt.Sprintf(
		"postgres://%s:%s@%s/%s",
		model.User, model.Password, model.Url, model.Database)
	conn, err := pgx.Connect(ctx, connStr)
	if err != nil {
		return err
	}
	defer conn.Close(ctx)
	// make sure the connection is available
	if err = conn.Ping(ctx); err != nil {
		return err
	}
	return nil
}

func checkBigQueryAccess(ctx context.Context, projectID, datasetID string) error {
	bqClient, err := newBigQueryClient(ctx, projectID)
	if err != nil {
		return err
	}
	defer bqClient.Close()
	// test get dataset metadata
	dataset := bqClient.Dataset(datasetID)
	if _, err := dataset.Metadata(ctx); err != nil {
		return errors.Errorf("failed to ping dataset `%s`: %v", datasetID, err)
	}
	return nil
}

func newBigQueryClient(ctx context.Context, projectID string) (*bigquery.Client, error) {
	opts := []option.ClientOption{}
	if _, err := os.Stat(credentialsFilePath); err == nil {
		// copy from gcs.go
		// use this opt only when file `CredentialsFilePath` exists
		// for some runtime gke, can get creds from node sa and don't relay on this file.
		opts = append(opts, option.WithCredentialsFile(credentialsFilePath))
	}
	client, err := bigquery.NewClient(ctx, projectID, opts...)
	if err != nil {
		return nil, errors.AddStack(err)
	}
	return client, nil
}
