package proxy

import (
	"context"
	"reflect"
	"sort"
	"sync"
	"testing"

	"github.com/docker/distribution"
)

type mockTagStore struct {
	mapping map[string]distribution.Descriptor
	sync.Mutex
}

var _ distribution.TagService = &mockTagStore{}

func (m *mockTagStore) Get(ctx context.Context, tag string) (distribution.Descriptor, error) {
	m.Lock()
	defer m.Unlock()

	if d, ok := m.mapping[tag]; ok {
		return d, nil
	}
	return distribution.Descriptor{}, distribution.ErrTagUnknown{}
}

func (m *mockTagStore) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error {
	m.Lock()
	defer m.Unlock()

	m.mapping[tag] = desc
	return nil
}

func (m *mockTagStore) Untag(ctx context.Context, tag string) error {
	m.Lock()
	defer m.Unlock()

	if _, ok := m.mapping[tag]; ok {
		delete(m.mapping, tag)
		return nil
	}
	return distribution.ErrTagUnknown{}
}

func (m *mockTagStore) All(ctx context.Context) ([]string, error) {
	m.Lock()
	defer m.Unlock()

	var tags []string
	for tag := range m.mapping {
		tags = append(tags, tag)
	}

	return tags, nil
}

func (m *mockTagStore) Lookup(ctx context.Context, digest distribution.Descriptor) ([]string, error) {
	panic("not implemented")
}

func testProxyTagService(local, remote map[string]distribution.Descriptor) *proxyTagService {
	if local == nil {
		local = make(map[string]distribution.Descriptor)
	}
	if remote == nil {
		remote = make(map[string]distribution.Descriptor)
	}
	return &proxyTagService{
		localTags:      &mockTagStore{mapping: local},
		remoteTags:     &mockTagStore{mapping: remote},
		authChallenger: &mockChallenger{},
	}
}

func TestGet(t *testing.T) {
	remoteDesc := distribution.Descriptor{Size: 42}
	remoteTag := "remote"
	proxyTags := testProxyTagService(map[string]distribution.Descriptor{remoteTag: remoteDesc}, nil)

	ctx := context.Background()

	// Get pre-loaded tag
	d, err := proxyTags.Get(ctx, remoteTag)
	if err != nil {
		t.Fatal(err)
	}

	if proxyTags.authChallenger.(*mockChallenger).count != 1 {
		t.Fatalf("Expected 1 auth challenge call, got %#v", proxyTags.authChallenger)
	}

	if !reflect.DeepEqual(d, remoteDesc) {
		t.Fatal("unable to get put tag")
	}

	local, err := proxyTags.localTags.Get(ctx, remoteTag)
	if err != nil {
		t.Fatal("remote tag not pulled into store")
	}

	if !reflect.DeepEqual(local, remoteDesc) {
		t.Fatalf("unexpected descriptor pulled through")
	}

	// Manually overwrite remote tag
	newRemoteDesc := distribution.Descriptor{Size: 43}
	err = proxyTags.remoteTags.Tag(ctx, remoteTag, newRemoteDesc)
	if err != nil {
		t.Fatal(err)
	}

	d, err = proxyTags.Get(ctx, remoteTag)
	if err != nil {
		t.Fatal(err)
	}

	if proxyTags.authChallenger.(*mockChallenger).count != 2 {
		t.Fatalf("Expected 2 auth challenge calls, got %#v", proxyTags.authChallenger)
	}

	if !reflect.DeepEqual(d, newRemoteDesc) {
		t.Fatal("unable to get put tag")
	}

	_, err = proxyTags.localTags.Get(ctx, remoteTag)
	if err != nil {
		t.Fatal("remote tag not pulled into store")
	}

	// untag, ensure it's removed locally, but present in remote
	err = proxyTags.Untag(ctx, remoteTag)
	if err != nil {
		t.Fatal(err)
	}

	_, err = proxyTags.localTags.Get(ctx, remoteTag)
	if err == nil {
		t.Fatalf("Expected error getting Untag'd tag")
	}

	_, err = proxyTags.remoteTags.Get(ctx, remoteTag)
	if err != nil {
		t.Fatalf("remote tag should not be untagged with proxyTag.Untag")
	}

	_, err = proxyTags.Get(ctx, remoteTag)
	if err != nil {
		t.Fatal("untagged tag should be pulled through")
	}

	if proxyTags.authChallenger.(*mockChallenger).count != 3 {
		t.Fatalf("Expected 3 auth challenge calls, got %#v", proxyTags.authChallenger)
	}

	// Add another tag.  Ensure both tags appear in 'All'
	err = proxyTags.remoteTags.Tag(ctx, "funtag", distribution.Descriptor{Size: 42})
	if err != nil {
		t.Fatal(err)
	}

	all, err := proxyTags.All(ctx)
	if err != nil {
		t.Fatal(err)
	}

	if len(all) != 2 {
		t.Fatalf("Unexpected tag length returned from All() : %d ", len(all))
	}

	sort.Strings(all)
	if all[0] != "funtag" && all[1] != "remote" {
		t.Fatalf("Unexpected tags returned from All() : %v ", all)
	}

	if proxyTags.authChallenger.(*mockChallenger).count != 4 {
		t.Fatalf("Expected 4 auth challenge calls, got %#v", proxyTags.authChallenger)
	}
}
