/*
 * 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 client

import (
	"context"

	"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/remote"
	"github.com/google/go-containerregistry/pkg/v1/remote/transport"
)

type ImageDescr struct {
	ConfigFile *pkg.ConfigFile `json:"configFile,omitempty"`
	Manifest   *pkg.Manifest   `json:"manifest,omitempty"`
	Tags       []string        `json:"avilableTags,omitempty"`
}

func (cli *Client) ImageInfo(ctx context.Context, imagepath string) (*ImageDescr, error) {
	var err error
	res := &ImageDescr{}

	imagepath, username, password, err := repackReference(imagepath)
	if err != nil {
		return res, err
	}
	options := make([]crane.Option, 0)
	options = append(options, crane.WithContext(ctx))

	ref, err := name.ParseReference(imagepath)
	if err != nil {
		return res, err
	}
	repo := ref.Context()
	if err != nil {
		return res, err
	}

	if username != "" && password != "" {
		defaultTransport := &roundTripper{}
		scopes := []string{repo.Scope(transport.PullScope)}

		regName := repo.RegistryStr()
		reg, err := name.NewRegistry(regName)
		if err != nil {
			return res, err
		}
		basicAuth := &authn.Basic{
			Username: username,
			Password: password,
		}
		authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
		if err != nil {
			return res, err
		}
		options = append(options, crane.WithTransport(authTransport))
	} else {
		transport := &roundTripper{}
		options = append(options, crane.WithTransport(transport))
	}

	image, err := crane.Pull(imagepath, options...)
	if err != nil {
		return res, err
	}

	config, err := image.ConfigFile()
	if err != nil {
		return res, err
	}
	res.ConfigFile = config

	manifest, err := image.Manifest()
	if err != nil {
		return res, err
	}
	res.Manifest = manifest

	return res, err

	remoteOptions := make([]remote.Option, 0)
	remoteOptions = append(remoteOptions, remote.WithContext(ctx))

	if username != "" && password != "" {
		defaultTransport := &roundTripper{}
		scopes := []string{repo.Scope(transport.PullScope)}

		regName := repo.RegistryStr()
		reg, err := name.NewRegistry(regName)
		if err != nil {
			return res, err
		}
		basicAuth := &authn.Basic{
			Username: username,
			Password: password,
		}
		authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
		if err != nil {
			return res, err
		}
		remoteOptions = append(remoteOptions, remote.WithTransport(authTransport))
	} else {
		transport := &roundTripper{}
		options = append(options, crane.WithTransport(transport))
	}

	tags, err := remote.List(repo, remoteOptions...)
	if err != nil {
		return res, err
	}
	res.Tags = tags

	return res, err
}
