// Copyright 2017 The kubecfg authors
//
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

package utils

import (
	"bytes"
	"context"
	"fmt"

	"github.com/genuinetools/reg/registry"
	"github.com/genuinetools/reg/repoutils"
)

const defaultRegistry = "registry-1.docker.io"	

// ImageName represents the parts of a docker image name
type ImageName struct {
	// eg: "myregistryhost:5000/fedora/httpd:version1.0"
	Registry   string // "myregistryhost:5000"
	Repository string // "fedora"
	Name       string // "httpd"
	Tag        string // "version1.0"
	Digest     string
}

// String implements the Stringer interface
func (n ImageName) String() string {
	buf := bytes.Buffer{}
	if n.Registry != "" {
		buf.WriteString(n.Registry)
		buf.WriteString("/")
	}
	if n.Repository != "" {
		buf.WriteString(n.Repository)
		buf.WriteString("/")
	}
	buf.WriteString(n.Name)
	if n.Digest != "" {
		buf.WriteString("@")
		buf.WriteString(n.Digest)
	} else {
		buf.WriteString(":")
		buf.WriteString(n.Tag)
	}
	return buf.String()
}

// RegistryRepoName returns the "repository" as used in the registry URL
func (n ImageName) RegistryRepoName() string {
	repo := n.Repository
	if repo == "" {
		repo = "library"
	}
	return fmt.Sprintf("%s/%s", repo, n.Name)
}

// RegistryURL returns the deduced base URL of the registry for this image
func (n ImageName) RegistryURL() string {
	reg := n.Registry
	if reg == "" {
		reg = defaultRegistry
	}
	return fmt.Sprintf("https://%s", reg)
}

// ParseImageName parses a docker image into an ImageName struct.
func ParseImageName(image string) (ImageName, error) {
	ret := ImageName{}

	img, err := registry.ParseImage(image)
	if err != nil {
		return ret, err
	}

	ret.Registry = img.Domain
	ret.Name = img.Path
	ret.Digest = img.Digest.String()
	ret.Tag = img.Tag

	return ret, nil
}

// Resolver is able to resolve docker image names into more specific forms
type Resolver interface {
	Resolve(image *ImageName) error
}

// NewIdentityResolver returns a resolver that does only trivial
// :latest canonicalisation
func NewIdentityResolver() Resolver {
	return identityResolver{}
}

type identityResolver struct{}

func (r identityResolver) Resolve(image *ImageName) error {
	return nil
}

// NewRegistryResolver returns a resolver that looks up a docker
// registry to resolve digests
func NewRegistryResolver(opt registry.Opt) Resolver {
	return &registryResolver{
		opt:   opt,
		cache: make(map[string]string),
	}
}

type registryResolver struct {
	opt   registry.Opt
	cache map[string]string
}

func (r *registryResolver) Resolve(n *ImageName) error {
	// TODO: get context from caller.
	ctx := context.Background()

	if n.Digest != "" {
		// Already has explicit digest
		return nil
	}

	if digest, ok := r.cache[n.String()]; ok {
		n.Digest = digest
		return nil
	}

	img, err := registry.ParseImage(n.String())
	if err != nil {
		return fmt.Errorf("unable to parse image name: %v", err)
	}

	auth, err := repoutils.GetAuthConfig("", "", img.Domain)
	if err != nil {
		return fmt.Errorf("unable to get auth config for registry: %v", err)
	}

	c, err := registry.New(ctx, auth, r.opt)
	if err != nil {
		return fmt.Errorf("unable to create registry client: %v", err)
	}

	digest, err := c.Digest(ctx, img)
	if err != nil {
		return fmt.Errorf("unable to get digest from the registry: %v", err)
	}

	n.Digest = digest.String()
	r.cache[n.String()] = n.Digest

	return nil
}
