package main

import (
	"archive/zip"
	"bytes"
	"errors"
	"fmt"
	"net/http"
	"path/filepath"

	"github.com/cenkalti/backoff/v4"
	"google.golang.org/protobuf/proto"

	bpb "source.monogon.dev/cloud/bmaas/server/api"
	"source.monogon.dev/metropolis/node/build/mkimage/osimage"
	"source.monogon.dev/metropolis/pkg/efivarfs"
	"source.monogon.dev/metropolis/pkg/logtree"
)

// install dispatches OSInstallationRequests to the appropriate installer
// method
func install(req *bpb.OSInstallationRequest, l logtree.LeveledLogger, isEFIBoot bool) error {
	switch reqT := req.Type.(type) {
	case *bpb.OSInstallationRequest_Metropolis:
		return installMetropolis(reqT.Metropolis, l, isEFIBoot)
	default:
		return errors.New("unknown installation request type")
	}
}

func installMetropolis(req *bpb.MetropolisInstallationRequest, l logtree.LeveledLogger, isEFIBoot bool) error {
	if !isEFIBoot {
		return errors.New("Monogon OS can only be installed on EFI-booted machines, this one is not")
	}
	// Download into a buffer as ZIP files cannot efficiently be read from
	// HTTP in Go as the ReaderAt has no way of indicating continuous sections,
	// thus a ton of small range requests would need to be used, causing
	// a huge latency penalty as well as costing a lot of money on typical
	// object storages. This should go away when we switch to a better bundle
	// format which can be streamed.
	var bundleRaw bytes.Buffer
	b := backoff.NewExponentialBackOff()
	err := backoff.Retry(func() error {
		bundleRes, err := http.Get(req.BundleUrl)
		if err != nil {
			l.Warningf("Metropolis bundle request failed: %v", err)
			return fmt.Errorf("HTTP request failed: %v", err)
		}
		defer bundleRes.Body.Close()
		switch bundleRes.StatusCode {
		case http.StatusTooEarly, http.StatusTooManyRequests,
			http.StatusInternalServerError, http.StatusBadGateway,
			http.StatusServiceUnavailable, http.StatusGatewayTimeout:
			l.Warningf("Metropolis bundle request HTTP %d error, retrying", bundleRes.StatusCode)
			return fmt.Errorf("HTTP error %d", bundleRes.StatusCode)
		default:
			// Non-standard code range used for proxy-related issue by various
			// vendors. Treat as non-permanent error.
			if bundleRes.StatusCode >= 520 && bundleRes.StatusCode < 599 {
				l.Warningf("Metropolis bundle request HTTP %d error, retrying", bundleRes.StatusCode)
				return fmt.Errorf("HTTP error %d", bundleRes.StatusCode)
			}
			if bundleRes.StatusCode != 200 {
				l.Errorf("Metropolis bundle request permanent HTTP %d error, aborting", bundleRes.StatusCode)
				return backoff.Permanent(fmt.Errorf("HTTP error %d", bundleRes.StatusCode))
			}
		}
		if _, err := bundleRaw.ReadFrom(bundleRes.Body); err != nil {
			l.Warningf("Metropolis bundle download failed, retrying: %v", err)
			bundleRaw.Reset()
			return err
		}
		return nil
	}, b)
	if err != nil {
		return fmt.Errorf("error downloading Metropolis bundle: %v", err)
	}
	l.Info("Metropolis Bundle downloaded")
	bundle, err := zip.NewReader(bytes.NewReader(bundleRaw.Bytes()), int64(bundleRaw.Len()))
	if err != nil {
		return fmt.Errorf("failed to open node bundle: %w", err)
	}
	efiPayload, err := bundle.Open("kernel_efi.efi")
	if err != nil {
		return fmt.Errorf("invalid bundle: %w", err)
	}
	defer efiPayload.Close()
	systemImage, err := bundle.Open("verity_rootfs.img")
	if err != nil {
		return fmt.Errorf("invalid bundle: %w", err)
	}
	defer systemImage.Close()

	nodeParamsRaw, err := proto.Marshal(req.NodeParameters)
	if err != nil {
		return fmt.Errorf("failed marshaling: %w", err)
	}

	installParams := osimage.Params{
		PartitionSize: osimage.PartitionSizeInfo{
			ESP:    128,
			System: 4096,
			Data:   128,
		},
		SystemImage:    systemImage,
		EFIPayload:     efiPayload,
		NodeParameters: bytes.NewReader(nodeParamsRaw),
		OutputPath:     filepath.Join("/dev", req.RootDevice),
	}

	be, err := osimage.Create(&installParams)
	if err != nil {
		return err
	}
	bootEntryIdx, err := efivarfs.CreateBootEntry(be)
	if err != nil {
		return fmt.Errorf("error creating EFI boot entry: %w", err)
	}
	if err := efivarfs.SetBootOrder(&efivarfs.BootOrder{uint16(bootEntryIdx)}); err != nil {
		return fmt.Errorf("error setting EFI boot order: %w", err)
	}
	l.Info("Metropolis installation completed")
	return nil
}
