//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/apache/cloudstack-go/v2/cloudstack"
)

var (
	CS_API_URL    = "http://localhost:8080/client/api"
	CS_API_KEY    = "valid-api-key"
	CS_SECRET_KEY = "valid-secret-key"
)

func CreateTestServer(t *testing.T, responses map[string]json.RawMessage) *httptest.Server {
	return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := responses[r.FormValue("command")]
		rawResult, _ := getRawValue(response)

		var result map[string]json.RawMessage
		err := json.Unmarshal(rawResult, &result)
		if err != nil {
			fmt.Fprintln(w, string(response))
			return
		}

		// Since we're using a sync client, pass the job result as the response
		val, ok := result["jobresult"]
		if !ok {
			fmt.Fprintln(w, string(response))
			return
		}

		err = json.Unmarshal(val, &result)
		if err != nil {
			fmt.Fprintln(w, string(response))
			return
		}

		// Handle success response separately
		if _, ok := result["success"]; ok {
			fmt.Fprintf(w, `{"jobresult":{"success":true}}`)
			return
		}

		fmt.Fprintln(w, string(val))

	}))
}

func getRawValue(b json.RawMessage) (json.RawMessage, error) {
	var m map[string]json.RawMessage
	if err := json.Unmarshal(b, &m); err != nil {
		return nil, err
	}
	for _, v := range m {
		return v, nil
	}
	return nil, fmt.Errorf("Unable to extract the raw value from:\n\n%s\n\n", string(b))
}

func readData(file string) (map[string]json.RawMessage, error) {
	var data map[string]json.RawMessage
	apis, err := ioutil.ReadFile("testdata/" + file + ".json")
	if err != nil {
		return nil, err
	}

	if err := json.Unmarshal(apis, &data); err != nil {
		return nil, err
	}

	return data, nil
}

func TestCreateAsyncClient(t *testing.T) {
	client := cloudstack.NewAsyncClient(CS_API_URL, CS_API_KEY, CS_SECRET_KEY, true)

	if client == nil {
		t.Errorf("Failed to create Cloudstack Async Client")
	}
}

func TestCreateSyncClient(t *testing.T) {
	client := cloudstack.NewClient(CS_API_URL, CS_API_KEY, CS_SECRET_KEY, true)

	if client == nil {
		t.Errorf("Failed to create Cloudstack Client")
	}
}

type UUIDStruct struct {
	Value cloudstack.UUID `json:"value"`
}

func TestUUID(t *testing.T) {
	valLong := `{"value": 4801878}`
	valString := `{"value": "994801878"}`
	valBool := `{"value": false}`
	res := UUIDStruct{}

	res.Value = ""
	if err := json.Unmarshal([]byte(valLong), &res); err != nil {
		t.Errorf("could not unserialize long into UUID: %s", err)
	}
	if res.Value != "4801878" {
		t.Errorf("unepected value '%s', expecting 4801878", res.Value)
	}

	res.Value = ""
	if err := json.Unmarshal([]byte(valString), &res); err != nil {
		t.Errorf("could not unserialize string into UUID: %s", err)
	}
	if res.Value != "994801878" {
		t.Errorf("unepected value '%s', expecting 994801878", res.Value)
	}

	res.Value = ""
	if err := json.Unmarshal([]byte(valBool), &res); err == nil {
		t.Errorf("missing expected error when serializing bool into UUID")
	}
}
