/*
Copyright (c) 2018 VMware, Inc. All Rights Reserved.

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 internal

import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"
	"net/url"

	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/types"
)

const (
	Path              = "/rest/com/vmware"
	SessionPath       = "/cis/session"
	CategoryPath      = "/cis/tagging/category"
	TagPath           = "/cis/tagging/tag"
	AssociationPath   = "/cis/tagging/tag-association"
	SessionCookieName = "vmware-api-session-id"
)

// AssociatedObject is the same structure as types.ManagedObjectReference,
// just with a different field name (ID instead of Value).
// In the API we use mo.Reference, this type is only used for wire transfer.
type AssociatedObject struct {
	Type  string `json:"type"`
	Value string `json:"id"`
}

// Reference implements mo.Reference
func (o AssociatedObject) Reference() types.ManagedObjectReference {
	return types.ManagedObjectReference(o)
}

// Association for tag-association requests.
type Association struct {
	ObjectID *AssociatedObject `json:"object_id,omitempty"`
}

// NewAssociation returns an Association, converting ref to an AssociatedObject.
func NewAssociation(ref mo.Reference) Association {
	obj := AssociatedObject(ref.Reference())
	return Association{
		ObjectID: &obj,
	}
}

type CloneURL interface {
	URL() *url.URL
}

// Resource wraps url.URL with helpers
type Resource struct {
	u *url.URL
}

func URL(c CloneURL, path string) *Resource {
	r := &Resource{u: c.URL()}
	r.u.Path = Path + path
	return r
}

// WithID appends id to the URL.Path
func (r *Resource) WithID(id string) *Resource {
	r.u.Path += "/id:" + id
	return r
}

// WithAction sets adds action to the URL.RawQuery
func (r *Resource) WithAction(action string) *Resource {
	r.u.RawQuery = url.Values{
		"~action": []string{action},
	}.Encode()
	return r
}

// Request returns a new http.Request for the given method.
// An optional body can be provided for POST and PATCH methods.
func (r *Resource) Request(method string, body ...interface{}) *http.Request {
	rdr := io.MultiReader() // empty body by default
	if len(body) != 0 {
		rdr = encode(body[0])
	}
	req, err := http.NewRequest(method, r.u.String(), rdr)
	if err != nil {
		panic(err)
	}
	return req
}

type errorReader struct {
	e error
}

func (e errorReader) Read([]byte) (int, error) {
	return -1, e.e
}

// encode body as JSON, deferring any errors until io.Reader is used.
func encode(body interface{}) io.Reader {
	var b bytes.Buffer
	err := json.NewEncoder(&b).Encode(body)
	if err != nil {
		return errorReader{err}
	}
	return &b
}
