// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package disco

import (
	"io/ioutil"
	"reflect"
	"strings"
	"testing"
)

var stringSchema = &Schema{
	Type: "string",
	Kind: SimpleKind,
}

func TestDocument(t *testing.T) {
	bytes, err := ioutil.ReadFile("testdata/test-api.json")
	if err != nil {
		t.Fatal(err)
	}
	got, err := NewDocument(bytes)
	if err != nil {
		t.Fatal(err)
	}
	want := &Document{
		ID:                "storage:v1",
		Name:              "storage",
		Version:           "v1",
		Title:             "Cloud Storage JSON API",
		RootURL:           "https://www.googleapis.com/",
		ServicePath:       "storage/v1/",
		BasePath:          "/storage/v1/",
		DocumentationLink: "https://developers.google.com/storage/docs/json_api/",
		Auth: Auth{
			OAuth2Scopes: []Scope{
				{"https://www.googleapis.com/auth/cloud-platform",
					"View and manage your data across Google Cloud Platform services"},
				{"https://www.googleapis.com/auth/cloud-platform.read-only",
					"View your data across Google Cloud Platform services"},
				{"https://www.googleapis.com/auth/devstorage.full_control",
					"Manage your data and permissions in Google Cloud Storage"},
				{"https://www.googleapis.com/auth/devstorage.read_only",
					"View your data in Google Cloud Storage"},
				{"https://www.googleapis.com/auth/devstorage.read_write",
					"Manage your data in Google Cloud Storage"},
			},
		},
		Features: []string{"dataWrapper"},
		Schemas: map[string]*Schema{
			"Bucket": &Schema{
				Name:        "Bucket",
				ID:          "Bucket",
				Type:        "object",
				Description: "A bucket.",
				Kind:        StructKind,
				Properties: []*Property{
					{"cors", &Schema{
						Type: "array",
						Kind: ArrayKind,
						ItemSchema: &Schema{
							Type: "object",
							Kind: StructKind,
							Properties: []*Property{
								{"maxAgeSeconds", &Schema{
									Type:   "integer",
									Format: "int32",
									Kind:   SimpleKind,
								}},
								{"method", &Schema{
									Type:       "array",
									Kind:       ArrayKind,
									ItemSchema: stringSchema,
								}},
							},
						},
					}},
					{"id", stringSchema},
					{"kind", &Schema{
						Type:    "string",
						Kind:    SimpleKind,
						Default: "storage#bucket",
					}},
				},
			},
			"Buckets": &Schema{
				ID:   "Buckets",
				Name: "Buckets",
				Type: "object",
				Kind: StructKind,
				Properties: []*Property{
					{"items", &Schema{
						Type: "array",
						Kind: ArrayKind,
						ItemSchema: &Schema{
							Kind:      ReferenceKind,
							Ref:       "Bucket",
							RefSchema: nil,
						},
					}},
				},
			},
			"VariantExample": &Schema{
				ID:   "VariantExample",
				Name: "VariantExample",
				Type: "object",
				Kind: StructKind,
				Variant: &Variant{
					Discriminant: "type",
					Map: []*VariantMapItem{
						{TypeValue: "Bucket", Ref: "Bucket"},
						{TypeValue: "Buckets", Ref: "Buckets"},
					},
				},
			},
		},
		Methods: MethodList{
			&Method{
				Name:       "getCertForOpenIdConnect",
				ID:         "oauth2.getCertForOpenIdConnect",
				Path:       "oauth2/v1/certs",
				HTTPMethod: "GET",
				Response:   &Schema{Ref: "Bucket", Kind: ReferenceKind},
			},
		},
		Resources: ResourceList{
			&Resource{
				Name:     "buckets",
				FullName: ".buckets",
				Methods: MethodList{
					&Method{
						Name:        "get",
						ID:          "storage.buckets.get",
						Path:        "b/{bucket}",
						HTTPMethod:  "GET",
						Description: "d",
						Parameters: ParameterList{
							&Parameter{
								Name: "bucket",
								Schema: Schema{
									Type: "string",
								},
								Required: true,
								Location: "path",
							},
							&Parameter{
								Name: "ifMetagenerationMatch",
								Schema: Schema{
									Type:   "string",
									Format: "int64",
								},
								Location: "query",
							},
							&Parameter{
								Name: "projection",
								Schema: Schema{
									Type:  "string",
									Enums: []string{"full", "noAcl"},
									EnumDescriptions: []string{
										"Include all properties.",
										"Omit owner, acl and defaultObjectAcl properties.",
									},
								},
								Location: "query",
							},
						},
						ParameterOrder: []string{"bucket"},
						Response:       &Schema{Ref: "Bucket", Kind: ReferenceKind},
						Scopes: []string{
							"https://www.googleapis.com/auth/cloud-platform",
							"https://www.googleapis.com/auth/cloud-platform.read-only",
							"https://www.googleapis.com/auth/devstorage.full_control",
							"https://www.googleapis.com/auth/devstorage.read_only",
							"https://www.googleapis.com/auth/devstorage.read_write",
						},
						SupportsMediaDownload: true,
						MediaUpload: &MediaUpload{
							Accept:  []string{"application/octet-stream"},
							MaxSize: "1GB",
							Protocols: map[string]Protocol{
								"simple": Protocol{
									Multipart: true,
									Path:      "/upload/customDataSources/{customDataSourceId}/uploads",
								},
								"resumable": Protocol{
									Multipart: true,
									Path:      "/resumable/upload/customDataSources/{customDataSourceId}/uploads",
								},
							},
						},
					},
				},
			},
		},
	}
	// Resolve schema references.
	bucket := want.Schemas["Bucket"]
	want.Schemas["Buckets"].Properties[0].Schema.ItemSchema.RefSchema = bucket
	want.Methods[0].Response.RefSchema = bucket
	want.Resources[0].Methods[0].Response.RefSchema = bucket
	for k, gs := range got.Schemas {
		ws := want.Schemas[k]
		if !reflect.DeepEqual(gs, ws) {
			t.Fatalf("schema %s: got\n%+v\nwant\n%+v", k, gs, ws)
		}
	}
	if len(got.Schemas) != len(want.Schemas) {
		t.Errorf("want %d schemas, got %d", len(got.Schemas), len(want.Schemas))
	}
	compareMethodLists(t, got.Methods, want.Methods)
	for i, gr := range got.Resources {
		wr := want.Resources[i]
		compareMethodLists(t, gr.Methods, wr.Methods)
		if !reflect.DeepEqual(gr, wr) {
			t.Fatalf("resource %d: got\n%+v\nwant\n%+v", i, gr, wr)
		}
	}
	if len(got.Resources) != len(want.Resources) {
		t.Errorf("want %d resources, got %d", len(got.Resources), len(want.Resources))
	}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("got\n%+v\nwant\n%+v", got, want)
	}
}

func compareMethodLists(t *testing.T, got, want MethodList) {
	if len(got) != len(want) {
		t.Fatalf("got %d methods, want %d", len(got), len(want))
	}
	for i, gm := range got {
		gm.JSONMap = nil // don't compare the raw JSON
		wm := want[i]
		if !reflect.DeepEqual(gm, wm) {
			t.Errorf("#%d: got\n%+v\nwant\n%+v", i, gm, wm)
		}
	}
}

func TestDocumentErrors(t *testing.T) {
	for _, in := range []string{
		`{"name": "X"`, // malformed JSON
		`{"id": 3}`,    // ID is an int instead of a string
		`{"auth": "oauth2": { "scopes": "string" }}`, // wrong auth structure
	} {
		_, err := NewDocument([]byte(in))
		if err == nil {
			t.Errorf("%s: got nil, want error", in)
		}
	}
}

func TestSchemaErrors(t *testing.T) {
	for _, s := range []*Schema{
		{Type: "array"},                         // missing item schema
		{Type: "string", ItemSchema: &Schema{}}, // items w/o array
		{Type: "moose"},                         // bad kind
		{Ref: "Thing"},                          // unresolved reference
	} {
		if err := s.init(nil); err == nil {
			t.Errorf("%+v: got nil, want error", s)
		}
	}
}

func TestErrorDoc(t *testing.T) {
	bytes, err := ioutil.ReadFile("testdata/error.json")
	if err != nil {
		t.Fatal(err)
	}
	if _, err := NewDocument(bytes); err == nil {
		t.Error("got nil, want error")
	} else if !strings.Contains(err.Error(), "404") {
		t.Errorf("got %v, want 404", err)
	}
}
