// Package localregistry implements a read-only OCI Distribution / Docker
// V2 container image registry backed by local layers.
package localregistry

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strconv"

	"github.com/docker/distribution"
	"github.com/docker/distribution/manifest/manifestlist"
	"github.com/docker/distribution/manifest/ocischema"
	"github.com/docker/distribution/manifest/schema2"
	"github.com/docker/distribution/reference"
	"github.com/opencontainers/go-digest"
	"google.golang.org/protobuf/encoding/prototext"

	"source.monogon.dev/metropolis/pkg/localregistry/spec"
)

type Server struct {
	manifests map[string][]byte
	blobs     map[digest.Digest]blobMeta
}

type blobMeta struct {
	filePath      string
	mediaType     string
	contentLength int64
}

func manifestDescriptorFromBazel(image *spec.Image) (manifestlist.ManifestDescriptor, error) {
	indexPath := filepath.Join(image.Path, "index.json")

	manifestListRaw, err := os.ReadFile(indexPath)
	if err != nil {
		return manifestlist.ManifestDescriptor{}, fmt.Errorf("while opening manifest list file: %w", err)
	}

	var imageManifestList manifestlist.ManifestList
	if err := json.Unmarshal(manifestListRaw, &imageManifestList); err != nil {
		return manifestlist.ManifestDescriptor{}, fmt.Errorf("while unmarshaling manifest list for %q: %w", image.Name, err)
	}

	if len(imageManifestList.Manifests) != 1 {
		return manifestlist.ManifestDescriptor{}, fmt.Errorf("unexpected manifest list length > 1")
	}

	return imageManifestList.Manifests[0], nil
}

func manifestFromBazel(s *Server, image *spec.Image, md manifestlist.ManifestDescriptor) (ocischema.Manifest, error) {
	manifestPath := filepath.Join(image.Path, "blobs", md.Digest.Algorithm().String(), md.Digest.Hex())
	manifestRaw, err := os.ReadFile(manifestPath)
	if err != nil {
		return ocischema.Manifest{}, fmt.Errorf("while opening manifest file: %w", err)
	}

	var imageManifest ocischema.Manifest
	if err := json.Unmarshal(manifestRaw, &imageManifest); err != nil {
		return ocischema.Manifest{}, fmt.Errorf("while unmarshaling manifest for %q: %w", image.Name, err)
	}

	// For Digest lookups
	s.manifests[image.Name] = manifestRaw
	s.manifests[md.Digest.String()] = manifestRaw

	return imageManifest, nil
}

func addBazelBlobFromDescriptor(s *Server, image *spec.Image, dd distribution.Descriptor) {
	path := filepath.Join(image.Path, "blobs", dd.Digest.Algorithm().String(), dd.Digest.Hex())
	s.blobs[dd.Digest] = blobMeta{filePath: path, mediaType: dd.MediaType, contentLength: dd.Size}
}

func FromBazelManifest(mb []byte) (*Server, error) {
	var bazelManifest spec.Manifest
	if err := prototext.Unmarshal(mb, &bazelManifest); err != nil {
		log.Fatalf("failed to parse manifest: %v", err)
	}
	s := Server{
		manifests: make(map[string][]byte),
		blobs:     make(map[digest.Digest]blobMeta),
	}
	for _, i := range bazelManifest.Images {
		md, err := manifestDescriptorFromBazel(i)
		if err != nil {
			return nil, err
		}

		addBazelBlobFromDescriptor(&s, i, md.Descriptor)

		m, err := manifestFromBazel(&s, i, md)
		if err != nil {
			return nil, err
		}

		addBazelBlobFromDescriptor(&s, i, m.Config)
		for _, l := range m.Layers {
			addBazelBlobFromDescriptor(&s, i, l)
		}
	}
	return &s, nil
}

var (
	versionCheckEp = regexp.MustCompile(`^/v2/$`)
	manifestEp     = regexp.MustCompile("^/v2/(" + reference.NameRegexp.String() + ")/manifests/(" + reference.TagRegexp.String() + "|" + digest.DigestRegexp.String() + ")$")
	blobEp         = regexp.MustCompile("^/v2/(" + reference.NameRegexp.String() + ")/blobs/(" + digest.DigestRegexp.String() + ")$")
)

func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if req.Method != http.MethodGet && req.Method != http.MethodHead {
		w.WriteHeader(http.StatusMethodNotAllowed)
		fmt.Fprintf(w, "Registry is read-only, only GET and HEAD are allowed\n")
		return
	}
	w.Header().Set("Content-Type", "application/json")
	if versionCheckEp.MatchString(req.URL.Path) {
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, "{}")
		return
	} else if matches := manifestEp.FindStringSubmatch(req.URL.Path); len(matches) > 0 {
		name := matches[1]
		manifest, ok := s.manifests[name]
		if !ok {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "Image not found")
			return
		}
		w.Header().Set("Content-Type", schema2.MediaTypeManifest)
		w.Header().Set("Content-Length", strconv.FormatInt(int64(len(manifest)), 10))
		w.WriteHeader(http.StatusOK)
		io.Copy(w, bytes.NewReader(manifest))
	} else if matches := blobEp.FindStringSubmatch(req.URL.Path); len(matches) > 0 {
		bm, ok := s.blobs[digest.Digest(matches[2])]
		if !ok {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "Blob not found")
			return
		}
		w.Header().Set("Content-Type", bm.mediaType)
		w.Header().Set("Content-Length", strconv.FormatInt(bm.contentLength, 10))
		http.ServeFile(w, req, bm.filePath)
	} else {
		w.WriteHeader(http.StatusNotFound)
	}
}
