package publishers

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/bazelbuild/continuous-integration/metrics/data"
	"github.com/bazelbuild/continuous-integration/metrics/metrics"
	_ "github.com/go-sql-driver/mysql"
)

const insertTemplate = "INSERT INTO %s (%s) VALUES (%s)"

type statement struct {
	prepared *sql.Stmt
	text     string
}

type CloudSql struct {
	conn       *sql.DB
	statements map[string]*statement
	gc         *CloudSqlGc
}

func (c *CloudSql) Name() string {
	return "Cloud SQL"
}

func (c *CloudSql) RegisterMetric(metric metrics.Metric) error {
	err := c.ensureTableExists(metric)
	if err != nil {
		return err
	}
	return c.prepareInsertStatement(metric)
}

func (c *CloudSql) ensureTableExists(metric metrics.Metric) error {
	// TODO(fweikert): implement
	return nil
}

func (c *CloudSql) prepareInsertStatement(metric metrics.Metric) error {
	name := metric.Name()
	if _, ok := c.statements[name]; ok {
		return fmt.Errorf("Metrics %s has already been registered for publisher %s.", name, c.Name())
	}

	columnNames := metrics.GetColumnNames(metric.Columns())
	placeholder := strings.TrimRight(strings.Repeat("?, ", len(columnNames)), ", ")
	insert := fmt.Sprintf(insertTemplate, name, strings.Join(columnNames, ", "), placeholder)

	nonKeyColumnNames := make([]string, 0)
	for _, c := range metric.Columns() {
		if !c.IsKey {
			nonKeyColumnNames = append(nonKeyColumnNames, c.Name)
		}
	}
	if len(nonKeyColumnNames) != len(columnNames) {
		updates := make([]string, len(nonKeyColumnNames))
		for i, c := range nonKeyColumnNames {
			updates[i] = fmt.Sprintf("%s=VALUES(%s)", c, c)
		}
		insert = fmt.Sprintf("%s ON DUPLICATE KEY UPDATE %s", insert, strings.Join(updates, ", "))
	}

	stmt, err := c.createStatement(name, insert)
	if err != nil {
		return err
	}
	c.statements[name] = stmt
	return nil
}

func (c *CloudSql) createStatement(metricName string, text string) (*statement, error) {
	stmt, err := c.conn.Prepare(text)
	if err != nil {
		return nil, fmt.Errorf("Failed to prepare statement for metric %s: %v\n\tStatement: %s", metricName, err, text)
	}
	return &statement{prepared: stmt, text: text}, nil
}

func (c *CloudSql) Publish(metric metrics.Metric, newData data.DataSet) error {
	metricName := metric.Name()
	stmt := c.statements[metricName]
	if stmt == nil {
		return fmt.Errorf("Could not find prepared insert statement for metric %s. Have you called RegisterMetric() first?", metricName)
	}

	for _, row := range newData.GetData().Data {
		_, err := stmt.prepared.Exec(row...)
		if err != nil {
			values := make([]string, len(row))
			for i, v := range row {
				values[i] = fmt.Sprintf("%v", v)
			}
			return fmt.Errorf("Could not insert new data for metric %s: %v\n\tStatement: %s\n\tValues: %s", metricName, err, stmt.text, strings.Join(values, ", "))
		}
	}

	if gcm, ok := metric.(metrics.GarbageCollectedMetric); ok {
		collected, err := c.gc.Run(gcm)
		if err != nil {
			return err
		}
		log.Printf("Cloud SQL: Garbage collection deleted %d entries for metric %s", collected, metricName)
	}
	return nil
}

func CreateCloudSqlPublisher(user, password, instance, database string, localPort int) (*CloudSql, error) {
	conn, err := sql.Open("mysql", getConnectionString(user, password, instance, database, localPort))
	if err != nil {
		return nil, fmt.Errorf("Could not establish connection to database: %v", err)
	}
	if err := conn.Ping(); err != nil {
		conn.Close()
		return nil, fmt.Errorf("Connection to database is bad: %v", err)
	}

	gc, err := CreateCloudSqlGc(conn)
	if err != nil {
		conn.Close()
		return nil, fmt.Errorf("Failed to create garbage collection module for Cloud SQL: %v", err)
	}
	return &CloudSql{
		conn:       conn,
		statements: make(map[string]*statement),
		gc:         gc,
	}, nil
}

func getConnectionString(user, password, instance, database string, localPort int) string {
	cred := fmt.Sprintf("%s:%s@", user, password)
	if os.Getenv("GAE_INSTANCE") != "" {
		// Running in production.
		return fmt.Sprintf("%sunix(/cloudsql/%s)/%s", cred, instance, database)
	}
	return fmt.Sprintf("%stcp([localhost]:%d)/%s", cred, localPort, database)
}
