package bmdb

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"time"

	"github.com/cockroachdb/cockroach-go/v2/crdb"
	"github.com/google/uuid"
	"github.com/lib/pq"
	"k8s.io/klog/v2"

	"source.monogon.dev/cloud/bmaas/bmdb/model"
)

// StartSession creates a new BMDB session which will be maintained in a
// background goroutine as long as the given context is valid. Each Session is
// represented by an entry in a sessions table within the BMDB, and subsequent
// Transact calls emit SQL transactions which depend on that entry still being
// present and up to date. A garbage collection system (to be implemented) will
// remove expired sessions from the BMDB, but this mechanism is not necessary
// for the session expiry mechanism to work.
//
// When the session becomes invalid (for example due to network partition),
// subsequent attempts to call Transact will fail with ErrSessionExpired. This
// means that the caller within the component is responsible for recreating a
// new Session if a previously used one expires.
func (c *Connection) StartSession(ctx context.Context) (*Session, error) {
	intervalSeconds := 5

	res, err := model.New(c.db).NewSession(ctx, model.NewSessionParams{
		SessionComponentName:   c.bmdb.ComponentName,
		SessionRuntimeInfo:     c.bmdb.RuntimeInfo,
		SessionIntervalSeconds: int64(intervalSeconds),
	})
	if err != nil {
		return nil, fmt.Errorf("creating session failed: %w", err)
	}

	klog.Infof("Started session %s", res.SessionID)

	ctx2, ctxC := context.WithCancel(ctx)

	s := &Session{
		connection: c,
		interval:   time.Duration(intervalSeconds) * time.Second,

		UUID: res.SessionID,

		ctx:  ctx2,
		ctxC: ctxC,
	}
	go s.maintainHeartbeat(ctx2)
	return s, nil
}

// Session is a session (identified by UUID) that has been started in the BMDB.
// Its liveness is maintained by a background goroutine, and as long as that
// session is alive, it can perform transactions and work on the BMDB.
type Session struct {
	connection *Connection
	interval   time.Duration

	UUID uuid.UUID

	ctx  context.Context
	ctxC context.CancelFunc
}

// Expired returns true if this session is expired and will fail all subsequent
// transactions/work.
func (s *Session) Expired() bool {
	return s.ctx.Err() != nil
}

// expire is a helper which marks this session as expired and returns
// ErrSessionExpired.
func (s *Session) expire() error {
	s.ctxC()
	return ErrSessionExpired
}

var (
	// ErrSessionExpired is returned when attempting to Transact or Work on a
	// Session that has expired or been canceled. Once a Session starts returning
	// these errors, it must be re-created by another StartSession call, as no other
	// calls will succeed.
	ErrSessionExpired = errors.New("session expired")
	// ErrWorkConflict is returned when attempting to Work on a Session with a
	// process name that's already performing some work, concurrently, on the
	// requested machine.
	ErrWorkConflict = errors.New("conflicting work on machine")
)

// maintainHeartbeat will attempt to repeatedly poke the session at a frequency
// twice of that of the minimum frequency mandated by the configured 5-second
// interval. It will exit if it detects that the session cannot be maintained
// anymore, canceling the session's internal context and causing future
// Transact/Work calls to fail.
func (s *Session) maintainHeartbeat(ctx context.Context) {
	// Internal deadline, used to check whether we haven't dropped the ball on
	// performing the updates due to a lot of transient errors.
	deadline := time.Now().Add(s.interval)
	for {
		if ctx.Err() != nil {
			klog.Infof("Session %s: context over, exiting: %v", s.UUID, ctx.Err())
			return
		}

		err := s.Transact(ctx, func(q *model.Queries) error {
			sessions, err := q.SessionCheck(ctx, s.UUID)
			if err != nil {
				return fmt.Errorf("when retrieving session: %w", err)
			}
			if len(sessions) < 1 {
				return s.expire()
			}
			err = q.SessionPoke(ctx, s.UUID)
			if err != nil {
				return fmt.Errorf("when poking session: %w", err)
			}
			return nil
		})
		if err != nil {
			klog.Errorf("Session %s: update failed: %v", s.UUID, err)
			if errors.Is(err, ErrSessionExpired) || deadline.After(time.Now()) {
				// No way to recover.
				klog.Errorf("Session %s: exiting", s.UUID)
				s.ctxC()
				return
			}
			// Just retry in a bit. One second seems about right for a 5 second interval.
			//
			// TODO(q3k): calculate this based on the configured interval.
			time.Sleep(time.Second)
		}
		// Success. Keep going.
		deadline = time.Now().Add(s.interval)
		select {
		case <-ctx.Done():
			// Do nothing, next loop iteration will exit.
		case <-time.After(s.interval / 2):
			// Do nothing, next loop iteration will heartbeat.
		}
	}
}

// Transact runs a given function in the context of both a CockroachDB and BMDB
// transaction, retrying as necessary.
//
// Most pure (meaning without side effects outside the database itself) BMDB
// transactions should be run this way.
func (s *Session) Transact(ctx context.Context, fn func(q *model.Queries) error) error {
	return crdb.ExecuteTx(ctx, s.connection.db, nil, func(tx *sql.Tx) error {
		qtx := model.New(tx)
		sessions, err := qtx.SessionCheck(ctx, s.UUID)
		if err != nil {
			return fmt.Errorf("when retrieving session: %w", err)
		}
		if len(sessions) < 1 {
			return s.expire()
		}

		if err := fn(qtx); err != nil {
			return err
		}

		return nil
	})
}

var (
	ErrNothingToDo = errors.New("nothing to do")
	// PostgresUniqueViolation is returned by the lib/pq driver when a mutation
	// cannot be performed due to a UNIQUE constraint being violated as a result of
	// the query.
	postgresUniqueViolation = pq.ErrorCode("23505")
)

// Work starts work on a machine. Full work execution is performed in three
// phases:
//
//  1. Retrieval phase. This is performed by 'fn' given to this function.
//     The retrieval function must return zero or more machines that some work
//     should be performed on per the BMDB. The first returned machine will be
//     locked for work under the given process and made available in the Work
//     structure returned by this call. The function may be called multiple times,
//     as it's run within a CockroachDB transaction which may be retried an
//     arbitrary number of times. Thus, it should be side-effect free, ideally only
//     performing read queries to the database.
//  2. Work phase. This is performed by user code while holding on to the Work
//     structure instance.
//  3. Commit phase. This is performed by the function passed to Work.Finish. See
//     that method's documentation for more details.
//
// Important: after retrieving Work successfully, either Finish or Cancel must be
// called, otherwise the machine will be locked until the parent session expires
// or is closed! It's safe and recommended to `defer work.Close()` after calling
// Work().
//
// If no machine is eligible for work, ErrNothingToDo should be returned by the
// retrieval function, and the same error (wrapped) will be returned by Work. In
// case the retrieval function returns no machines and no error, that error will
// also be returned.
//
// The returned Work object is _not_ goroutine safe.
func (s *Session) Work(ctx context.Context, process model.Process, fn func(q *model.Queries) ([]uuid.UUID, error)) (*Work, error) {
	var mid *uuid.UUID
	var exisingingBackoff *existingBackoff
	err := s.Transact(ctx, func(q *model.Queries) error {
		mids, err := fn(q)
		if err != nil {
			return fmt.Errorf("could not retrieve machines for work: %w", err)
		}
		if len(mids) < 1 {
			return ErrNothingToDo
		}
		mid = &mids[0]
		err = q.StartWork(ctx, model.StartWorkParams{
			MachineID: mids[0],
			SessionID: s.UUID,
			Process:   process,
		})
		if err != nil {
			var perr *pq.Error
			if errors.As(err, &perr) && perr.Code == postgresUniqueViolation {
				return ErrWorkConflict
			}
			return fmt.Errorf("could not start work on %q: %w", mids[0], err)
		}
		err = q.WorkHistoryInsert(ctx, model.WorkHistoryInsertParams{
			MachineID: mids[0],
			Event:     model.WorkHistoryEventStarted,
			Process:   process,
		})
		if err != nil {
			return fmt.Errorf("could not insert history event: %w", err)
		}
		backoffs, err := q.WorkBackoffOf(ctx, model.WorkBackoffOfParams{
			MachineID: mids[0],
			Process:   process,
		})
		if err != nil {
			return fmt.Errorf("could not get backoffs: %w", err)
		}
		if len(backoffs) > 0 {
			// If the backoff exists but the last interval is null (e.g. is from a previous
			// version of the schema when backoffs had no interval data) pretend it doesn't
			// exist. Then the backoff mechanism can restart from a clean slate and populate
			// a new, full backoff row.
			if backoff := backoffs[0]; backoff.LastIntervalSeconds.Valid {
				klog.Infof("Existing backoff: %d seconds", backoff.LastIntervalSeconds.Int64)
				exisingingBackoff = &existingBackoff{
					lastInterval: time.Second * time.Duration(backoff.LastIntervalSeconds.Int64),
				}
			}
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	klog.Infof("Started work %q on machine %q (sess %q)", process, *mid, s.UUID)
	return &Work{
		Machine: *mid,
		s:       s,
		process: process,
		backoff: exisingingBackoff,
	}, nil
}

// existingBackoff contains backoff information retrieved from a work item that
// has previously failed with a backoff.
type existingBackoff struct {
	// lastInterval is the last interval as stored in the backoff table.
	lastInterval time.Duration
}

// Backoff describes the configuration of backoff for a failed work item. It can
// be passed to Work.Fail to cause an item to not be processed again (to be 'in
// backoff') for a given period of time. Exponential backoff can be configured so
// that subsequent failures of a process will have exponentially increasing
// backoff periods, up to some maximum length.
//
// The underlying unit of backoff period length in the database is one second.
// What that means is that all effective calculated backoff periods must be an
// integer number of seconds. This is performed by always rounding up this period
// to the nearest second. A side effect of this is that with exponential backoff,
// non-integer exponents will be less precisely applied for small backoff values,
// e.g. an exponent of 1.1 with initial backoff of 1s will generate the following
// sequence of backoff periods:
//
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17
//
// Which corresponds to the following approximate multipliers in between periods:
//
// 2.00, 1.50, 1.33, 1.25, 1.20, 1.17, 1.14, 1.12, 1.11, 1.10, 1.18, 1.15, 1.13
//
// Thus, the exponent value should be treated more as a limit that the sequence
// of periods will approach than a hard rule for calculating the periods.
// However, if the exponent is larger than 1 (i.e. any time exponential backoff
// is requested), this guarantees that the backoff won't get 'stuck' on a
// repeated period value due to a rounding error.
//
// A zero backoff structure is valid and represents a non-exponential backoff of
// one second.
//
// A partially filled structure is also valid. See the field comments for more
// information about how fields are capped if not set. The described behaviour
// allows for two useful shorthands:
//
//  1. If only Initial is set, then the backoff is non-exponential and will always
//     be of value Initial (or whatever the previous period already persisted the
//     database).
//  2. If only Maximum and Exponent are set, the backoff will be exponential,
//     starting at one second, and exponentially increasing to Maximum.
//
// It is recommended to construct Backoff structures as const values and treat
// them as read-only 'descriptors', one per work kind / process.
//
// One feature currently missing from the Backoff implementation is jitter. This
// might be introduced in the future if deemed necessary.
type Backoff struct {
	// Initial backoff period, used for the backoff if this item failed for the first
	// time (i.e. has not had a Finish call in between two Fail calls).
	//
	// Subsequent calls will ignore this field if the backoff is exponential. If
	// non-exponential, the initial time will always override whatever was previously
	// persisted in the database, i.e. the backoff will always be of value 'Initial'.
	//
	// Cannot be lower than one second. If it is, it will be capped to it.
	Initial time.Duration `u:"initial"`

	// Maximum time for backoff. If the calculation of the next back off period
	// (based on the Exponent and last backoff value) exceeds this maximum, it will
	// be capped to it.
	//
	// Maximum is not persisted in the database. Instead, it is always read from this
	// structure.
	//
	// Cannot be lower than Initial. If it is, it will be capped to it.
	Maximum time.Duration `u:"maximum"`

	// Exponent used for next backoff calculation. Any time a work item fails
	// directly after another failure, the previous backoff period will be multiplied
	// by the exponent to yield the new backoff period. The new period will then be
	// capped to Maximum.
	//
	// Exponent is not persisted in the database. Instead, it is always read from
	// this structure.
	//
	// Cannot be lower than 1.0. If it is, it will be capped to it.
	Exponent float64 `u:"exponent"`
}

// normalized copies the given backoff and returns a 'normalized' version of it,
// with the 'when zero/unset' rules described in the Backoff documentation
// strings.
func (b *Backoff) normalized() *Backoff {
	c := *b

	if c.Exponent < 1.0 {
		c.Exponent = 1.0
	}
	if c.Initial < time.Second {
		c.Initial = time.Second
	}
	if c.Maximum < c.Initial {
		c.Maximum = c.Initial
	}
	return &c
}

func (b *Backoff) simple() bool {
	// Non-normalized simple backoffs will have a zero exponent.
	if b.Exponent == 0.0 {
		return true
	}
	// Normalized simple backoffs will have a 1.0 exponent.
	if b.Exponent == 1.0 {
		return true
	}
	return false
}

// next calculates the backoff period based on a backoff descriptor and previous
// existing backoff information. Both or either can be nil.
func (b *Backoff) next(e *existingBackoff) int64 {
	second := time.Second.Nanoseconds()

	// Minimum interval is one second. Start with that.
	last := second
	// Then, if we have a previous interval, and it's greater than a second, use that
	// as the last interval.
	if e != nil {
		if previous := e.lastInterval.Nanoseconds(); previous > second {
			last = previous
		}
	}

	// If no backoff is configured, go with either the minimum of one second, or
	// whatever the last previous interval was.
	if b == nil {
		return last / second
	}

	// Make a copy of the backoff descriptor, normalizing as necessary.
	c := b.normalized()

	// Simple backoffs always return Initial.
	if b.simple() {
		return c.Initial.Nanoseconds() / second
	}

	// If there is no existing backoff, return the initial backoff value directly.
	if e == nil {
		return c.Initial.Nanoseconds() / second
	}

	// Start out with the persisted interval.
	next := last
	// If by any chance we persisted an interval less than one second, clamp it.
	if next < second {
		next = second
	}

	// Multiply by exponent from descriptor.
	next = int64(float64(next) * c.Exponent)

	// Handle overflows. If multiplying by a positive number resulted in a lower
	// value than what we started with, it means we overflowed and wrapped around. If
	// so, clamp to maximum.
	if next < last {
		next = c.Maximum.Nanoseconds()
	}

	// Clamp to maximum.
	if next > c.Maximum.Nanoseconds() {
		next = c.Maximum.Nanoseconds()
	}
	// Round up to the nearest second.
	if next%second == 0 {
		return next / second
	} else {
		return next/second + 1
	}
}

// Work being performed on a machine.
type Work struct {
	// Machine that this work is being performed on, as retrieved by the retrieval
	// function passed to the Work method.
	Machine uuid.UUID
	// s is the parent session.
	s *Session
	// done marks that this work has already been canceled or finished.
	done bool
	// process that this work performs.
	process model.Process

	backoff *existingBackoff
}

// Cancel the Work started on a machine. If the work has already been finished
// or canceled, this is a no-op. In case of error, a log line will be emitted.
func (w *Work) Cancel(ctx context.Context) {
	if w.done {
		return
	}
	w.done = true

	klog.Infof("Canceling work %q on machine %q (sess %q)", w.process, w.Machine, w.s.UUID)
	// Eat error and log. There's nothing we can do if this fails, and if it does, it's
	// probably because our connectivity to the BMDB has failed. If so, our session
	// will be invalidated soon and so will the work being performed on this
	// machine.
	err := w.s.Transact(ctx, func(q *model.Queries) error {
		err := q.FinishWork(ctx, model.FinishWorkParams{
			MachineID: w.Machine,
			SessionID: w.s.UUID,
			Process:   w.process,
		})
		if err != nil {
			return err
		}
		return q.WorkHistoryInsert(ctx, model.WorkHistoryInsertParams{
			MachineID: w.Machine,
			Process:   w.process,
			Event:     model.WorkHistoryEventCanceled,
		})
	})
	if err != nil {
		klog.Errorf("Failed to cancel work %q on %q (sess %q): %v", w.process, w.Machine, w.s.UUID, err)
	}
}

// Finish work by executing a commit function 'fn' and releasing the machine
// from the work performed. The function given should apply tags to the
// processed machine in a way that causes it to not be eligible for retrieval
// again. As with the retriever function, the commit function might be called an
// arbitrary number of times as part of cockroachdb transaction retries.
//
// This may be called only once.
func (w *Work) Finish(ctx context.Context, fn func(q *model.Queries) error) error {
	if w.done {
		return fmt.Errorf("already finished")
	}
	w.done = true
	klog.Infof("Finishing work %q on machine %q (sess %q)", w.process, w.Machine, w.s.UUID)
	return w.s.Transact(ctx, func(q *model.Queries) error {
		err := q.FinishWork(ctx, model.FinishWorkParams{
			MachineID: w.Machine,
			SessionID: w.s.UUID,
			Process:   w.process,
		})
		if err != nil {
			return err
		}
		err = q.WorkBackoffDelete(ctx, model.WorkBackoffDeleteParams{
			MachineID: w.Machine,
			Process:   w.process,
		})
		if err != nil {
			return err
		}
		err = q.WorkHistoryInsert(ctx, model.WorkHistoryInsertParams{
			MachineID: w.Machine,
			Process:   w.process,
			Event:     model.WorkHistoryEventFinished,
		})
		if err != nil {
			return err
		}
		return fn(q)
	})
}

// Fail work and introduce backoff. The given cause is an operator-readable
// string that will be persisted alongside the backoff and the work history/audit
// table.
//
// The backoff describes a period during which the same process will not be
// retried on this machine until its expiration.
//
// The given backoff is a structure which describes both the initial backoff
// period if the work failed for the first time, and a mechanism to exponentially
// increase the backoff period if that work failed repeatedly. The work is
// defined to have failed repeatedly if it only resulted in Cancel/Fail calls
// without any Finish calls in the meantime.
//
// Only the last backoff period is persisted in the database. The exponential
// backoff behaviour (including its maximum time) is always calculated based on
// the given backoff structure.
//
// If nil, the backoff defaults to a non-exponential, one second backoff. This is
// the minimum designed to keep the system chugging along without repeatedly
// trying a failed job in a loop. However, the backoff should generally be set to
// some well engineered value to prevent spurious retries.
func (w *Work) Fail(ctx context.Context, backoff *Backoff, cause string) error {
	if w.done {
		return fmt.Errorf("already finished")
	}
	w.done = true

	return w.s.Transact(ctx, func(q *model.Queries) error {
		err := q.FinishWork(ctx, model.FinishWorkParams{
			MachineID: w.Machine,
			SessionID: w.s.UUID,
			Process:   w.process,
		})
		if err != nil {
			return err
		}
		err = q.WorkHistoryInsert(ctx, model.WorkHistoryInsertParams{
			MachineID: w.Machine,
			Process:   w.process,
			Event:     model.WorkHistoryEventFailed,
			FailedCause: sql.NullString{
				String: cause,
				Valid:  true,
			},
		})
		if err != nil {
			return err
		}
		if backoff == nil {
			klog.Warningf("Nil backoff for %q on machine %q: defaulting to one second non-exponential.", w.process, w.Machine)
		}
		seconds := backoff.next(w.backoff)
		klog.Infof("Adding backoff for %q on machine %q: %d seconds", w.process, w.Machine, seconds)
		return q.WorkBackoffInsert(ctx, model.WorkBackoffInsertParams{
			MachineID: w.Machine,
			Process:   w.process,
			Cause:     cause,
			Seconds:   seconds,
		})
	})
}
