package handler

// |@@| C

import (
	"context"
	"database/sql"
	"encoding/json"
	"gardening/src/lib/spy"
	"gardening/src/lib/sql_db"
	"gardening/src/lib/time"
)

type Handler struct {
	SqlDb *sql_db.SqlDb
	Spy   *spy.Spy
	Time  time.Time
}

type HandlerMod struct {
	Tx      *sql.Tx
	Id      string
	Table   string
	Fields  []string
	Columns []string
	Values  []interface{}
}

func (this *HandlerMod) Printable() string {
	st := struct {
		Id      string
		Table   string
		Fields  []string
		Columns []string
		Values  []interface{}
	}{
		Id:      this.Id,
		Table:   this.Table,
		Fields:  this.Fields,
		Columns: this.Columns,
		Values:  this.Values,
	}
	s, _ := json.Marshal(st)
	return string(s)
}

func (this *Handler) Create(ctx context.Context, mod *HandlerMod) (string, int, error) {
	this.Spy.LogRecord(ctx, spy.RecordKindHandlerCreate, mod)
	return this.SqlDb.Create(ctx, mod.Tx, mod.Table, mod.Columns, mod.Values)
}

func (this *Handler) Update(ctx context.Context, mod *HandlerMod) (int, error) {
	this.Spy.LogRecord(ctx, spy.RecordKindHandlerUpdate, mod)
	return this.SqlDb.Update(ctx, mod.Tx, mod.Table, mod.Id, mod.Columns, mod.Values)
}

func (this *Handler) Delete(ctx context.Context, mod *HandlerMod) (int, error) {
	this.Spy.LogRecord(ctx, spy.RecordKindHandlerDelete, mod)
	return this.SqlDb.Delete(ctx, mod.Tx, mod.Table, mod.Id)
}

func (this *Handler) IndexesFromFields(fields []string, tableFields []string) []int {
	var indexes []int
	for _, fieldLooked := range fields {
		for i, tableField := range tableFields {
			if tableField == fieldLooked {
				indexes = append(indexes, i)
			}
		}
	}
	return indexes
}

func (this *Handler) StringSubsetFromIndexes(indexes []int, set []string) []string {
	var subset []string
	for _, index := range indexes {
		subset = append(subset, set[index])
	}
	return subset
}

func (this *Handler) InterfaceSubsetFromIndexes(indexes []int, set []interface{}) []interface{} {
	var subset []interface{}
	for _, index := range indexes {
		subset = append(subset, set[index])
	}
	return subset
}

func (this *Handler) ExcludeUtilitiesIndexes(indexes []int, fields []string) []int {
	var out []int
	for _, index := range indexes {
		if fields[index] == "Id" {
			continue
		}
		if fields[index] == "CreatedAt" {
			continue
		}
		if fields[index] == "UpdatedAt" {
			continue
		}
		if fields[index] == "UpdatedBy" {
			continue
		}
		out = append(out, index)
	}
	return out
}

func (this *Handler) AppendColumnValueAtNow(column string, mod *HandlerMod) {
	mod.Columns = append(mod.Columns, column)
	mod.Values = append(mod.Values, this.Time.Now())
}
