// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

package shepherd

import (
	"context"
	"fmt"
	"net/netip"

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

var ErrMachineNotFound = fmt.Errorf("machine not found")
var ErrNotImplemented = fmt.Errorf("not implemented")

// ProviderID is an opaque unique identifier for a machine within a single
// provider instance. It is generated by the Provider and usually the same
// as the ID of the machine within the system that the Provider managed.
// The Shepherd (and BMaaS in general) requires these IDs to be unique
// within a provider and stable.
type ProviderID string

const InvalidProviderID ProviderID = "invalid"

// IsValid reports whether the ProviderID is valid.
func (p ProviderID) IsValid() bool {
	return p != InvalidProviderID
}

// Availability defines the availability state according to the provider.
// See the different states for more information.
type Availability int

const (
	// AvailabilityUndefined is used as a placeholder to prevent that the default
	// value can create any type of bad behaviour.
	AvailabilityUndefined Availability = iota
	// AvailabilityPossiblyUsed defines the state where a machine is possibly used,
	// this is a state for use in stateless providers where the shepherd has
	// to check against the bmdb if Machine.ID is already provisioned or not.
	// These machines must have a valid ID and Addr.
	AvailabilityPossiblyUsed
	// AvailabilityKnownUnused defines the state where a machine is know to be free,
	// e.g. a hardware reservation at equinix. These machines may not have an
	// ID or Addr.
	AvailabilityKnownUnused
	// AvailabilityKnownUsed defines the state where a machine is known to be used,
	// e.g. a deployed machine that is in use. These machines must have a
	// valid ID and Addr.
	AvailabilityKnownUsed
)

func (a Availability) String() string {
	switch a {
	case AvailabilityUndefined:
		return "Undefined"
	case AvailabilityKnownUnused:
		return "KnownUnused"
	case AvailabilityKnownUsed:
		return "KnownUsed"
	case AvailabilityPossiblyUsed:
		return "PossiblyUsed"
	default:
		return fmt.Sprintf("<invalid value %d>", a)
	}
}

type Machine interface {
	// ID returns the provider id, see ProviderID for more information.
	ID() ProviderID
	// Addr returns the machines ip address that is reachable from the
	// shepherd. It is used to connect to the machine via SSH to execute
	// all takeover tasks, etc.
	Addr() netip.Addr
	// Availability returns the availability of the machine.
	Availability() Availability
	// Failed should return true if the machine is in a failed state and
	// should be ignored if there are inconsistencies between the provider
	// and BMDB.
	Failed() bool
}

type CreateMachineRequest struct {
	// UnusedMachine resembles a machine to use as deployment target.
	UnusedMachine Machine
}

// Provider is the interface that is used to abstract the interaction between
// the shepherd and machine providers like Equinix. All methods inside this
// interface must not be called concurrently.
type Provider interface {
	// ListMachines returns all existing machines for a provider. Machines
	// that are still in the state of being created by CreateMachine should
	// not be returned.
	ListMachines(context.Context) ([]Machine, error)

	// GetMachine returns an existing machine for a provider. Machines
	// that are still in the state of being created by CreateMachine should
	// not be returned. If a there are no machines found after these filters
	// an error should be returned.
	GetMachine(context.Context, ProviderID) (Machine, error)

	// CreateMachine creates a new machine with the given parameters and
	// returns the created instance. The provider is required to create the
	// entry into the machine table and MachineProvided tag. If there are no
	// more machines avaiable, an error should be returned.
	CreateMachine(context.Context, *bmdb.Session, CreateMachineRequest) (Machine, error)

	// Type returns the value that represents this provider inside the database.
	Type() model.Provider
}

type Recoverer interface {
	Provider

	// RebootMachine tries to bring a machine back from the dead by e.g. rebooting
	RebootMachine(context.Context, ProviderID) error

	// ReinstallMachine should reinstall the given machine and if the provider
	// does not support reinstallation, the function should return an error
	// stating this. If reinstalled, the installed tag should be updated to
	// allow the reconcile loop to restart the takeover process.
	ReinstallMachine(context.Context, ProviderID) error
}
