package distribution

import (
	"encoding/json"
	"fmt"
	"io"
	"runtime"

	"github.com/docker/distribution"
	"github.com/docker/distribution/manifest/schema2"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/distribution/metadata"
	"github.com/docker/docker/distribution/xfer"
	"github.com/docker/docker/image"
	"github.com/docker/docker/layer"
	"github.com/docker/docker/pkg/progress"
	refstore "github.com/docker/docker/reference"
	"github.com/docker/docker/registry"
	"github.com/docker/libtrust"
	"github.com/opencontainers/go-digest"
	"golang.org/x/net/context"
)

// Config stores configuration for communicating
// with a registry.
type Config struct {
	// MetaHeaders stores HTTP headers with metadata about the image
	MetaHeaders map[string][]string
	// AuthConfig holds authentication credentials for authenticating with
	// the registry.
	AuthConfig *types.AuthConfig
	// ProgressOutput is the interface for showing the status of the pull
	// operation.
	ProgressOutput progress.Output
	// RegistryService is the registry service to use for TLS configuration
	// and endpoint lookup.
	RegistryService registry.Service
	// ImageEventLogger notifies events for a given image
	ImageEventLogger func(id, name, action string)
	// MetadataStore is the storage backend for distribution-specific
	// metadata.
	MetadataStore metadata.Store
	// ImageStore manages images.
	ImageStore ImageConfigStore
	// ReferenceStore manages tags. This value is optional, when excluded
	// content will not be tagged.
	ReferenceStore refstore.Store
	// RequireSchema2 ensures that only schema2 manifests are used.
	RequireSchema2 bool
}

// ImagePullConfig stores pull configuration.
type ImagePullConfig struct {
	Config

	// DownloadManager manages concurrent pulls.
	DownloadManager RootFSDownloadManager
	// Schema2Types is the valid schema2 configuration types allowed
	// by the pull operation.
	Schema2Types []string
}

// ImagePushConfig stores push configuration.
type ImagePushConfig struct {
	Config

	// ConfigMediaType is the configuration media type for
	// schema2 manifests.
	ConfigMediaType string
	// LayerStore manages layers.
	LayerStore PushLayerProvider
	// TrustKey is the private key for legacy signatures. This is typically
	// an ephemeral key, since these signatures are no longer verified.
	TrustKey libtrust.PrivateKey
	// UploadManager dispatches uploads.
	UploadManager *xfer.LayerUploadManager
}

// ImageConfigStore handles storing and getting image configurations
// by digest. Allows getting an image configurations rootfs from the
// configuration.
type ImageConfigStore interface {
	Put([]byte) (digest.Digest, error)
	Get(digest.Digest) ([]byte, error)
	RootFSFromConfig([]byte) (*image.RootFS, error)
}

// PushLayerProvider provides layers to be pushed by ChainID.
type PushLayerProvider interface {
	Get(layer.ChainID) (PushLayer, error)
}

// PushLayer is a pushable layer with metadata about the layer
// and access to the content of the layer.
type PushLayer interface {
	ChainID() layer.ChainID
	DiffID() layer.DiffID
	Parent() PushLayer
	Open() (io.ReadCloser, error)
	Size() (int64, error)
	MediaType() string
	Release()
}

// RootFSDownloadManager handles downloading of the rootfs
type RootFSDownloadManager interface {
	// Download downloads the layers into the given initial rootfs and
	// returns the final rootfs.
	// Given progress output to track download progress
	// Returns function to release download resources
	Download(ctx context.Context, initialRootFS image.RootFS, layers []xfer.DownloadDescriptor, progressOutput progress.Output) (image.RootFS, func(), error)
}

type imageConfigStore struct {
	image.Store
}

// NewImageConfigStoreFromStore returns an ImageConfigStore backed
// by an image.Store for container images.
func NewImageConfigStoreFromStore(is image.Store) ImageConfigStore {
	return &imageConfigStore{
		Store: is,
	}
}

func (s *imageConfigStore) Put(c []byte) (digest.Digest, error) {
	id, err := s.Store.Create(c)
	return digest.Digest(id), err
}

func (s *imageConfigStore) Get(d digest.Digest) ([]byte, error) {
	img, err := s.Store.Get(image.IDFromDigest(d))
	if err != nil {
		return nil, err
	}
	return img.RawJSON(), nil
}

func (s *imageConfigStore) RootFSFromConfig(c []byte) (*image.RootFS, error) {
	var unmarshalledConfig image.Image
	if err := json.Unmarshal(c, &unmarshalledConfig); err != nil {
		return nil, err
	}

	// fail immediately on Windows when downloading a non-Windows image
	// and vice versa
	if runtime.GOOS == "windows" && unmarshalledConfig.OS == "linux" {
		return nil, fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
	} else if runtime.GOOS != "windows" && unmarshalledConfig.OS == "windows" {
		return nil, fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
	}

	return unmarshalledConfig.RootFS, nil
}

type storeLayerProvider struct {
	ls layer.Store
}

// NewLayerProviderFromStore returns a layer provider backed by
// an instance of LayerStore. Only getting layers as gzipped
// tars is supported.
func NewLayerProviderFromStore(ls layer.Store) PushLayerProvider {
	return &storeLayerProvider{
		ls: ls,
	}
}

func (p *storeLayerProvider) Get(lid layer.ChainID) (PushLayer, error) {
	if lid == "" {
		return &storeLayer{
			Layer: layer.EmptyLayer,
		}, nil
	}
	l, err := p.ls.Get(lid)
	if err != nil {
		return nil, err
	}

	sl := storeLayer{
		Layer: l,
		ls:    p.ls,
	}
	if d, ok := l.(distribution.Describable); ok {
		return &describableStoreLayer{
			storeLayer:  sl,
			describable: d,
		}, nil
	}

	return &sl, nil
}

type storeLayer struct {
	layer.Layer
	ls layer.Store
}

func (l *storeLayer) Parent() PushLayer {
	p := l.Layer.Parent()
	if p == nil {
		return nil
	}
	sl := storeLayer{
		Layer: p,
		ls:    l.ls,
	}
	if d, ok := p.(distribution.Describable); ok {
		return &describableStoreLayer{
			storeLayer:  sl,
			describable: d,
		}
	}

	return &sl
}

func (l *storeLayer) Open() (io.ReadCloser, error) {
	return l.Layer.TarStream()
}

func (l *storeLayer) Size() (int64, error) {
	return l.Layer.DiffSize()
}

func (l *storeLayer) MediaType() string {
	// layer store always returns uncompressed tars
	return schema2.MediaTypeUncompressedLayer
}

func (l *storeLayer) Release() {
	if l.ls != nil {
		layer.ReleaseAndLog(l.ls, l.Layer)
	}
}

type describableStoreLayer struct {
	storeLayer
	describable distribution.Describable
}

func (l *describableStoreLayer) Descriptor() distribution.Descriptor {
	return l.describable.Descriptor()
}
