/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 */
package gcrcli

import (
	"context"
	"fmt"
	"os"

	"mstore/pkg/auxtool"
	"mstore/pkg/auxutar"

	"github.com/google/go-containerregistry/pkg/authn"
	"github.com/google/go-containerregistry/pkg/crane"
	"github.com/google/go-containerregistry/pkg/name"
	pkg "github.com/google/go-containerregistry/pkg/v1"
	"github.com/google/go-containerregistry/pkg/v1/layout"
	"github.com/google/go-containerregistry/pkg/v1/remote/transport"
)

func (cli *Client) PushImage(ctx context.Context, filepath, imagepath string) error {
	var err error

	imagepath, username, password, err := repackReference(imagepath)
	if err != nil {
		return err
	}
	options := make([]crane.Option, 0)
	options = append(options, crane.WithContext(ctx))
	if username != "" && password != "" {
		ref, err := name.ParseReference(imagepath)
		if err != nil {
			return err
		}
		repo := ref.Context()
		if err != nil {
			return err
		}
		defaultTransport := NewRoundTripper(cli.skipTLSVerify)

		scopes := []string{
			repo.Scope(transport.PushScope),
			repo.Scope(transport.PullScope),
		}

		regName := repo.RegistryStr()
		reg, err := name.NewRegistry(regName)
		if err != nil {
			return err
		}
		basicAuth := &authn.Basic{
			Username: username,
			Password: password,
		}

		authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
		if err != nil {
			return err
		}
		options = append(options, crane.WithTransport(authTransport))
	} else {
		defaultTransport := NewRoundTripper(cli.skipTLSVerify)
		options = append(options, crane.WithTransport(defaultTransport))
	}

	dstdir := auxtool.MakeTmpFilename(filepath)
	err = auxutar.Unarchive(filepath, dstdir)
	defer os.RemoveAll(dstdir)
	if err != nil {
		return err
	}
	image, err := imageLoader(dstdir)
	if err != nil {
		return err
	}
	err = crane.Push(image, imagepath, options...)
	if err != nil {
		return err
	}
	return err
}

func imageLoader(dirPath string) (pkg.Image, error) {
	var err error
	var res pkg.Image
	layoutPath, err := layout.FromPath(dirPath)
	if err != nil {
		return res, err
	}
	imageIndex, err := layoutPath.ImageIndex()
	if err != nil {
		return res, err
	}
	indexManifest, err := imageIndex.IndexManifest()
	if err != nil {
		return res, err
	}
	if indexManifest == nil {
		err := fmt.Errorf("Empty indexManifest referency")
		return res, err
	}

	manifest := indexManifest.Manifests[0]
	image, err := layoutPath.Image(manifest.Digest)
	if err != nil {
		return res, err
	}
	res = image
	return res, err
}
