//
// 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 cloudstack

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestNetworkService_CreateNetwork(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiName := "createNetwork"
		response, err := ReadData(apiName, "NetworkService")
		if err != nil {
			t.Errorf("Failed to read response data due to: %v", err)
		}
		fmt.Fprintf(writer, response[apiName])
	}))
	defer server.Close()
	client := NewClient(server.URL, "APIKEY", "SECRETKEY", false)
	params := client.Network.NewCreateNetworkParams("testIsolatedNet", "testIsolatedNet", "69b7f746-208a-47c3-a940-4d3ebb720372", "04ccc336-d730-42fe-8ff6-5ae36e141e81")
	resp, err := client.Network.CreateNetwork(params)
	if err != nil {
		t.Errorf("Failed to create network due to: %v", err)
	}
	if resp == nil || resp.Name != "testIsolatedNet" {
		t.Errorf("Failed to create network")
	}
}

func TestNetworkService_ListNetworks(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiName := "listNetworks"
		response, err := ReadData(apiName, "NetworkService")
		if err != nil {
			t.Errorf("Failed to read response data due to: %v", err)
		}
		fmt.Fprintf(writer, response[apiName])
	}))
	defer server.Close()
	client := NewClient(server.URL, "APIKEY", "SECRETKEY", false)
	params := client.Network.NewListNetworksParams()
	params.SetId("eb9c270d-dd66-443b-9524-ada1eff4442a")
	resp, err := client.Network.ListNetworks(params)
	if err != nil {
		t.Errorf("Failed to list specific network details due to : %v", err)
	}
	if resp.Count != 1 {
		t.Errorf("Failed to list specific network details")
	}
	if resp.Networks[0].Id != "eb9c270d-dd66-443b-9524-ada1eff4442a" {
		t.Errorf("Failed to list specific network details")
	}
}

func TestNetworkService_DeleteNetwork(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiName := "deleteNetwork"
		response, err := ParseAsyncResponse(apiName, "NetworkService", *request)
		if err != nil {
			t.Errorf("Failed to parse response, due to: %v", err)
		}

		fmt.Fprintf(writer, response)
	}))
	defer server.Close()
	client := NewAsyncClient(server.URL, "APIKEY", "SECRETKEY", false)
	params := client.Network.NewDeleteNetworkParams("eb9c270d-dd66-443b-9524-ada1eff4442a")
	resp, err := client.Network.DeleteNetwork(params)
	if err != nil {
		t.Errorf("Failed to delete network due to: %v", err)
		return
	}
	if resp == nil || !resp.Success {
		t.Errorf("Failed to delete network")
	}
}

//func TestNetworkService_RestartNetworkWithCleanUp(t *testing.T) {
//	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
//		responses := map[string]string{
//			"restartNetwork": `{
//				"restartnetworkresponse": {
//					"jobid": "09b1ab5d-02d0-410f-b373-6520962b98eb"
//				}
//			}`,
//			"queryAsyncJobResult": `{
//				"queryasyncjobresultresponse": {
//					"accountid": "27ef5ba2-5fe0-11ea-9a56-1e006800018c",
//					"userid": "27f2484f-5fe0-11ea-9a56-1e006800018c",
//					"cmd": "org.apache.cloudstack.api.command.user.network.RestartNetworkCmd",
//					"jobstatus": 1,
//					"jobprocstatus": 0,
//					"jobresultcode": 0,
//					"jobresulttype": "object",
//					"jobresult": {
//						"success": true
//					},
//					"created": "2021-10-04T05:37:23+0000",
//					"completed": "2021-10-04T05:37:41+0000",
//					"jobid": "09b1ab5d-02d0-410f-b373-6520962b98eb"
//				}
//			}`,
//		}
//		fmt.Fprintf(writer, responses[request.FormValue("command")])
//	}))
//	defer server.Close()
//	client := NewAsyncClient(server.URL, "APIKEY", "SECRETKEY", false)
//	params := client.Network.NewRestartNetworkParams("30358053-0f9d-4112-9948-976477896db6")
//	params.SetCleanup(true)
//	_, err := client.Network.RestartNetwork(params)
//	if err != nil {
//		t.Errorf("Failed to restart network with cleanup due to: %v", err)
//		return
//	}
//}

func TestNetworkService_CreatePhysicalNetwork(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiName := "createPhysicalNetwork"
		response, err := ParseAsyncResponse(apiName, "NetworkService", *request)
		if err != nil {
			t.Errorf("Failed to parse response, due to: %v", err)
		}
		fmt.Fprintf(writer, response)
	}))
	defer server.Close()
	client := NewAsyncClient(server.URL, "APIKEY", "SECRETKEY", false)
	params := client.Network.NewCreatePhysicalNetworkParams("testPhyNet", "d4a81f75-5d92-415e-ab59-e85cc2ce56d9")
	resp, err := client.Network.CreatePhysicalNetwork(params)
	if err != nil {
		t.Errorf("Failed to create physical network due to: %v", err)
		return
	}
	if resp == nil || resp.Name != "testPhyNet" {
		t.Errorf("Failed to create physical network")
	}
}
