/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 *
 * This work is published and licensed under a Creative Commons
 * Attribution-NonCommercial-NoDerivatives 4.0 International License.
 *
 * Distribution of this work is permitted, but commercial use and
 * modifications are strictly prohibited.
 */
package imageoper

import (
	"context"
	"fmt"
	"net/http"
	"strconv"

	"mstore/pkg/auxoci"
	"mstore/pkg/descr"
)

type GetManifestParams struct {
	Name      string
	Reference string
}
type GetManifestResult struct {
	ContentLength       string
	ContentType         string
	DockerContentDigest string
	Payload             string
}

func (oper *Operator) GetManifest(ctx context.Context, params *GetManifestParams) (*GetManifestResult, int, error) {
	var err error
	res := &GetManifestResult{}

	if params.Name == "" {
		err = fmt.Errorf("Empty name")
		return res, http.StatusBadRequest, err
	}
	if params.Reference == "" {
		err = fmt.Errorf("Empty reference")
		return res, http.StatusBadRequest, err
	}

	resName := params.Name
	oper.iLock.WaitAndLock(resName)
	defer oper.iLock.Done(resName)

	manifestDescr := descr.Manifest{}
	var exists bool
	// TODO: checking layers?
	if stringLikeSHADigest(params.Reference) {
		digest := normalizeSHADigest(params.Reference)
		exists, manifestDescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digest)
		if err != nil {
			return res, http.StatusInternalServerError, err
		}
		if !exists {
			return res, http.StatusNotFound, err
		}

		manifestDigest := auxoci.SHA256DigestFromString(manifestDescr.Payload)
		res.DockerContentDigest = manifestDigest.String()

		res.ContentLength = strconv.FormatInt(int64(len(manifestDescr.Payload)), 10)
		res.ContentType = manifestDescr.ContentType
		res.Payload = manifestDescr.Payload

	} else {
		// Create index of manifests
		exists, manifestDescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference)
		if err != nil {
			return res, http.StatusInternalServerError, err
		}
		if !exists {
			return res, http.StatusNotFound, err
		}
		/*
			index, indexBytes, err := indexFromManigestDescrs(manifestDescrs)
			if err != nil {
				return res, http.StatusInternalServerError, err
			}
			indexDigest := auxoci.SHA256DigestFromString(indexBytes)
			res.DockerContentDigest = indexDigest.String()

			res.ContentLength = strconv.FormatInt(int64(len(indexBytes)), 10)
			res.ContentType = index.MediaType
			res.Payload = string(indexBytes)
		*/
		manifestDescr = manifestDescrs[0]

		manifestDigest := auxoci.SHA256DigestFromString(manifestDescr.Payload)
		res.DockerContentDigest = manifestDigest.String()

		res.ContentLength = strconv.FormatInt(int64(len(manifestDescr.Payload)), 10)
		res.ContentType = manifestDescr.ContentType
		res.Payload = manifestDescr.Payload

	}
	return res, http.StatusOK, err
}
