// 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/bazelbuild/rules_go/go/runfiles"
	"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/test/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, err := runfiles.Rlocation(filepath.Join("_main", image.Path, "index.json"))
	if err != nil {
		return manifestlist.ManifestDescriptor{}, fmt.Errorf("while locating manifest list file: %w", err)
	}

	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, err := runfiles.Rlocation(filepath.Join("_main", image.Path, "blobs", md.Digest.Algorithm().String(), md.Digest.Hex()))
	if err != nil {
		return ocischema.Manifest{}, fmt.Errorf("while locating manifest file: %w", err)
	}
	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) error {
	path, err := runfiles.Rlocation(filepath.Join("_main", image.Path, "blobs", dd.Digest.Algorithm().String(), dd.Digest.Hex()))
	if err != nil {
		return fmt.Errorf("while locating blob: %w", err)
	}
	s.blobs[dd.Digest] = blobMeta{filePath: path, mediaType: dd.MediaType, contentLength: dd.Size}
	return nil
}

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
		}

		if err := addBazelBlobFromDescriptor(&s, i, md.Descriptor); err != nil {
			return nil, err
		}

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

		if err := addBazelBlobFromDescriptor(&s, i, m.Config); err != nil {
			return nil, err
		}
		for _, l := range m.Layers {
			if err := addBazelBlobFromDescriptor(&s, i, l); err != nil {
				return nil, err
			}
		}
	}
	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)
	}
}
