package main

import (
	"crypto/sha256"
	"database/sql"
	"encoding/json"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	_ "github.com/go-sql-driver/mysql"
	"github.com/labstack/echo"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
)

type ovirt struct {
}

var MySQLUSER = "apigw"
var MySQLPASS = "^_P+^7Q$bmPj+$xB"

func login(BA string) OvirtObject {
	url := OvirtURL + "/ovirt-engine/api"
	method := "GET"

	client := &http.Client{}
	req, err := http.NewRequest(method, url, nil)

	if err != nil {
		fmt.Println(err)
	}
	req.Header.Add("Version", "4")
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Authorization", BA)

	res, err := client.Do(req)
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	object := OvirtObject{}
	err = json.Unmarshal(body, &object)
	return object
}

type OvirtObject struct {
	ProductInfo struct {
		Name    string `json:"name"`
		Version struct {
			Build       string `json:"build"`
			FullVersion string `json:"full_version"`
			Major       string `json:"major"`
			Minor       string `json:"minor"`
			Revision    string `json:"revision"`
		} `json:"version"`
	} `json:"product_info"`
	SpecialObjects struct {
		BlankTemplate struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"blank_template"`
		RootTag struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"root_tag"`
	} `json:"special_objects"`
	Time              int64 `json:"time"`
	AuthenticatedUser struct {
		Href string `json:"href"`
		ID   string `json:"id"`
	} `json:"authenticated_user"`
	EffectiveUser struct {
		Href string `json:"href"`
		ID   string `json:"id"`
	} `json:"effective_user"`
	Link []struct {
		Href string `json:"href"`
		Rel  string `json:"rel"`
	} `json:"link"`
}
type TaskHeader struct {
	Name  string `json:"Name,omitempty"`
	Value string `json:"Value,omitempty"`
}
type addVMTask struct {
	URL     string `json:"url"`
	JSON    string `json:__json`
	Method  string `json:"method"`
	Headers []struct {
		Name  string `json:"Name,omitempty"`
		Value string `json:"Value,omitempty"`
	} `json:"headers"`
}
type AddVMRequest struct {
	URL  string `json:"url"`
	JSON struct {
		Name        string `json:"name"`
		Description string `json:"description"`
		Comment     string `json:"comment"`
		Cluster     struct {
			Name string `json:"name"`
		} `json:"cluster"`
		Template struct {
			Name string `json:"name"`
		} `json:"template"`
		CPU struct {
			Topology struct {
				Sockets string `json:"sockets"`
				Cores   string `json:"cores"`
				Threads string `json:"threads"`
			} `json:"topology"`
		} `json:"cpu"`
		Memory       string `json:"memory"`
		MemoryPolicy struct {
			Ballooning string `json:"ballooning"`
			Guaranteed string `json:"guaranteed"`
			OverCommit struct {
				Percent string `json:"percent"`
			} `json:"over_commit"`
		} `json:"memory_policy"`
	} `json:"JSON"`
	Method  string `json:"method"`
	Headers []struct {
		Name  string `json:"Name"`
		Value string `json:"Value"`
	} `json:"headers"`
}
type VMStatistics struct {
	Statistic []struct {
		Kind   string `json:"kind"`
		Type   string `json:"type"`
		Unit   string `json:"unit"`
		Values struct {
			Value []struct {
				Datum float64 `json:"datum"`
			} `json:"value"`
		} `json:"values"`
		VM struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"vm,omitempty"`
		Name        string `json:"name"`
		Description string `json:"description"`
		Href        string `json:"href,omitempty"`
		ID          string `json:"id"`
	} `json:"statistic"`
}

func (o ovirt) vmStatus(uuid string) string {
	type vmStatus struct {
		NextRunConfigurationExists string `json:"next_run_configuration_exists"`
		NumaTuneMode               string `json:"numa_tune_mode"`
		Status                     string `json:"status"`
		StopTime                   int64  `json:"stop_time"`
		OriginalTemplate           struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"original_template"`
		Template struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"template"`
		Actions struct {
			Link []struct {
				Href string `json:"href"`
				Rel  string `json:"rel"`
			} `json:"link"`
		} `json:"actions"`
		Name        string `json:"name"`
		Description string `json:"description"`
		Comment     string `json:"comment"`
		Href        string `json:"href"`
		ID          string `json:"id"`
		Bios        struct {
			BootMenu struct {
				Enabled string `json:"enabled"`
			} `json:"boot_menu"`
			Type string `json:"type"`
		} `json:"bios"`
		CPU struct {
			Architecture string `json:"architecture"`
			Topology     struct {
				Cores   string `json:"cores"`
				Sockets string `json:"sockets"`
				Threads string `json:"threads"`
			} `json:"topology"`
		} `json:"cpu"`
		Display struct {
			AllowOverride       string `json:"allow_override"`
			CopyPasteEnabled    string `json:"copy_paste_enabled"`
			DisconnectAction    string `json:"disconnect_action"`
			FileTransferEnabled string `json:"file_transfer_enabled"`
			Monitors            string `json:"monitors"`
			SingleQxlPci        string `json:"single_qxl_pci"`
			SmartcardEnabled    string `json:"smartcard_enabled"`
			Type                string `json:"type"`
		} `json:"display"`
		Initialization struct {
			AuthorizedSSHKeys        string `json:"authorized_ssh_keys"`
			CloudInitNetworkProtocol string `json:"cloud_init_network_protocol"`
			CustomScript             string `json:"custom_script"`
			HostName                 string `json:"host_name"`
			NicConfigurations        struct {
			} `json:"nic_configurations"`
			RegenerateSSHKeys string `json:"regenerate_ssh_keys"`
			UserName          string `json:"user_name"`
		} `json:"initialization"`
		Io struct {
			Threads string `json:"threads"`
		} `json:"io"`
		Memory    string `json:"memory"`
		Migration struct {
			AutoConverge string `json:"auto_converge"`
			Compressed   string `json:"compressed"`
			Encrypted    string `json:"encrypted"`
		} `json:"migration"`
		Origin string `json:"origin"`
		Os     struct {
			Boot struct {
				Devices struct {
					Device []string `json:"device"`
				} `json:"devices"`
			} `json:"boot"`
			Type string `json:"type"`
		} `json:"os"`
		Sso struct {
			Methods struct {
				Method []struct {
					ID string `json:"id"`
				} `json:"method"`
			} `json:"methods"`
		} `json:"sso"`
		Stateless string `json:"stateless"`
		Type      string `json:"type"`
		Usb       struct {
			Enabled string `json:"enabled"`
		} `json:"usb"`
		Cluster struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"cluster"`
		Quota struct {
			ID string `json:"id"`
		} `json:"quota"`
		Link []struct {
			Href string `json:"href"`
			Rel  string `json:"rel"`
		} `json:"link"`
		CPUShares        string `json:"cpu_shares"`
		CreationTime     int64  `json:"creation_time"`
		DeleteProtected  string `json:"delete_protected"`
		HighAvailability struct {
			Enabled  string `json:"enabled"`
			Priority string `json:"priority"`
		} `json:"high_availability"`
		LargeIcon struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"large_icon"`
		MemoryPolicy struct {
			Ballooning string `json:"ballooning"`
			Guaranteed string `json:"guaranteed"`
			Max        string `json:"max"`
		} `json:"memory_policy"`
		MigrationDowntime  string `json:"migration_downtime"`
		MultiQueuesEnabled string `json:"multi_queues_enabled"`
		PlacementPolicy    struct {
			Affinity string `json:"affinity"`
			Hosts    struct {
				Host []struct {
					Href string `json:"href"`
					ID   string `json:"id"`
				} `json:"host"`
			} `json:"hosts"`
		} `json:"placement_policy"`
		SmallIcon struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"small_icon"`
		StartPaused                 string `json:"start_paused"`
		StorageErrorResumeBehaviour string `json:"storage_error_resume_behaviour"`
		TimeZone                    struct {
			Name string `json:"name"`
		} `json:"time_zone"`
		CPUProfile struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"cpu_profile"`
	}
	//url := "https://ovirt-cl.zi-tel.com/ovirt-engine/api/vms/c1a44128-6c6c-406b-99d8-4a68a99380c9"
	url := OvirtURL + "/ovirt-engine/api/vms/" + uuid
	//fmt.Println("VMSTATUS UUID:" ,uuid)
	method := "GET"

	client := &http.Client{}
	req, err := http.NewRequest(method, url, nil)

	if err != nil {
		return "Null"
	}
	req.Header.Add("Version", "4")
	req.Header.Add("Accept", "application/json")
	//TODO: replace BA
	req.Header.Add("Authorization", "Basic YWRtaW5AaW50ZXJuYWw6a2VsYW5zaCBqMw==")

	res, err := client.Do(req)
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)

	//fmt.Println("full response: ",string(body))
	_vmstatus := vmStatus{}
	_err := json.Unmarshal(body, &_vmstatus)
	if _err != nil {
		fmt.Println("Error in vmStatus ", _err)
	}
	return _vmstatus.Status
}
func (o ovirt) addvm(c echo.Context) error {
	type AddVMPayment struct {
		Data struct {
			Price struct {
				CPU    string `json:"cpu"`
				Mem    string `json:"mem"`
				Disk   string `json:"disk"`
				Nic    string `json:"nic"`
				Period string `json:"period"`
			} `json:"price"`
			InvoiceUUID string `json:"invoiceUUID"`
		} `json:"data"`
		Message string `json:"message"`
		Origin  string `json:"origin"`
		Code    int    `json:"code"`
	}
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	_sha256 := sha256.Sum256([]byte(string(claims["name"].(string))))
	var hashChannel_ = make(chan []byte, 1)
	hashChannel_ <- _sha256[:]
	token := decrypt(<-hashChannel_, claims["IPAToken"].(string))
	_BA := strings.Split(token, ";")
	BA := _BA[len(_BA)-2]
	var vmname, vmdescr, vmcomment, templatename, cpuSock, cpuCore, cpuThread, mem, Disk, nic, period string
	vmname = c.FormValue("VmName")
	vmdescr = c.FormValue("VmDescr")
	vmcomment = c.FormValue("VmComment")
	templatename = c.FormValue("VmTempl")
	cpuThread = c.FormValue("VmCPU")
	Disk = c.FormValue("VmDisk")
	period = c.FormValue("VmPeriod")
	nic = c.FormValue("VmNIC")
	sshKey := c.FormValue("sshKey")
	rootpass := c.FormValue("rootpass")
	cpuCore = "1"
	cpuSock = "1"
	mem = c.FormValue("VmMem")
	url := OvirtURL + "/ovirt-engine/api/vms"
	method := "POST"
	//TODO: Encrypt this Json
	//	_json := fmt.Sprintf(`
	//{
	//    "name": "%s",
	//    "description": "%s",
	//    "comment": "%s",
	//    "cluster": {
	//        "name": "Default"
	//    },
	//    "template": {
	//        "name": "%s"
	//    },
	//    "cpu": {
	//        "topology": {
	//            "sockets": "%s",
	//            "cores": "%s",
	//            "threads": "%s"
	//        }
	//    },
	//    "memory": "%s",
	//    "memory_policy": {
	//        "ballooning": "true",
	//        "guaranteed": "%s",
	//        "over_commit": {
	//            "percent": "10"
	//        }
	//    }
	//}
	//`, vmname, vmdescr, vmcomment, templatename, cpuSock, cpuCore, cpuThread, mem, mem)
	// Change as task
	//change to task//	payload := strings.NewReader(_json)
	//change to task//	//tr := &http.Transport{
	//change to task//	//	TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	//change to task//	//}
	//change to task//	client := &http.Client{}
	//change to task//	req, err := http.NewRequest(method, url, payload)
	//change to task//	if err != nil {
	//change to task//		fmt.Println(err)
	//change to task//	}
	//change to task//	req.Header.Add("Version", "4")
	//change to task//	req.Header.Add("Accept", "application/json")
	//change to task//	req.Header.Add("Authorization", BA)
	//change to task//	req.Header.Add("Content-Type", "application/json")
	//change to task//	res, err := client.Do(req)
	//change to task//	body, err := ioutil.ReadAll(res.Body)
	//change to task//	//fmt.Println("len: ", len(_json))
	//change to task//	//fmt.Println("res:", res)
	//change to task//	if err != nil || res.StatusCode != 202 {
	//change to task//		resp := _response{
	//change to task//			Origin:  "ovirt-addvm",
	//change to task//			Message: res.Status,
	//change to task//			Code:    1001,
	//change to task//		}
	//change to task//		b, _ := json.MarshalIndent(resp, "", "  ")
	//change to task//		return c.String(http.StatusBadRequest, string(b))
	//change to task//	}
	//change to task//	defer res.Body.Close()
	//addvmresponse := AddVMResponse{}O
	newvm := AddVMRequest{
		URL: url,
		JSON: struct {
			Name        string `json:"name"`
			Description string `json:"description"`
			Comment     string `json:"comment"`
			Cluster     struct {
				Name string `json:"name"`
			} `json:"cluster"`
			Template struct {
				Name string `json:"name"`
			} `json:"template"`
			CPU struct {
				Topology struct {
					Sockets string `json:"sockets"`
					Cores   string `json:"cores"`
					Threads string `json:"threads"`
				} `json:"topology"`
			} `json:"cpu"`
			Memory       string `json:"memory"`
			MemoryPolicy struct {
				Ballooning string `json:"ballooning"`
				Guaranteed string `json:"guaranteed"`
				OverCommit struct {
					Percent string `json:"percent"`
				} `json:"over_commit"`
			} `json:"memory_policy"`
		}{
			Name:        vmname,
			Description: vmdescr,
			Comment:     vmcomment,
			Cluster: struct {
				Name string `json:"name"`
			}{Name: "Default"},
			Template: struct {
				Name string `json:"name"`
			}{Name: templatename},
			CPU: struct {
				Topology struct {
					Sockets string `json:"sockets"`
					Cores   string `json:"cores"`
					Threads string `json:"threads"`
				} `json:"topology"`
			}{
				struct {
					Sockets string `json:"sockets"`
					Cores   string `json:"cores"`
					Threads string `json:"threads"`
				}{
					Sockets: cpuSock,
					Cores:   cpuCore,
					Threads: cpuThread,
				},
			},
			Memory: mem,
			MemoryPolicy: struct {
				Ballooning string `json:"ballooning"`
				Guaranteed string `json:"guaranteed"`
				OverCommit struct {
					Percent string `json:"percent"`
				} `json:"over_commit"`
			}{
				Ballooning: "true",
				Guaranteed: mem,
				OverCommit: struct {
					Percent string `json:"percent"`
				}{Percent: "10"},
			},
		},
		Method:  method,
		Headers: nil,
	}
	newvm.Headers = append(newvm.Headers, struct {
		Name  string `json:"Name"`
		Value string `json:"Value"`
	}{
		Name:  "Accept",
		Value: "application/json",
	})
	newvm.Headers = append(newvm.Headers, struct {
		Name  string `json:"Name"`
		Value string `json:"Value"`
	}{
		Name:  "Authorization",
		Value: BA,
	})
	newvm.Headers = append(newvm.Headers, struct {
		Name  string `json:"Name"`
		Value string `json:"Value"`
	}{
		Name:  "Content-Type",
		Value: "application/json",
	})
	uuid, _ := uuidgen("APIGW-Ovirt-addVMTask")
	invoiceUUID, _ := uuidgen("APIGW-FakeInvoice")
	responseInvoiece := AddVMPayment{
		Data: struct {
			Price struct {
				CPU    string `json:"cpu"`
				Mem    string `json:"mem"`
				Disk   string `json:"disk"`
				Nic    string `json:"nic"`
				Period string `json:"period"`
			} `json:"price"`
			InvoiceUUID string `json:"invoiceUUID"`
		}{
			Price: struct {
				CPU    string `json:"cpu"`
				Mem    string `json:"mem"`
				Disk   string `json:"disk"`
				Nic    string `json:"nic"`
				Period string `json:"period"`
			}{
				CPU:    cpuThread,
				Mem:    mem,
				Disk:   Disk,
				Nic:    nic,
				Period: period,
			},
			InvoiceUUID: invoiceUUID,
		},
		Message: "Done",
		Origin:  "AddVM",
		Code:    1000,
	}
	__createVM, _ := json.MarshalIndent(newvm, "", "  ")
	// Add VM Task
	addTask(uuid, string(__createVM), "", "APIGW", "VM Creation for "+claims["name"].(string), invoiceUUID, "0", "0")

	{
		db, err := sql.Open("mysql", MySQLUSER+":"+MySQLPASS+"@tcp(127.0.0.1:3306)/zicloud")
		if err != nil {
			resp := _response{
				Origin:  "ovirt-addvm",
				Message: "Error on connecting db for save add vm result",
				Code:    1001,
			}
			b, _ := json.MarshalIndent(resp, "", "  ")
			return c.String(http.StatusBadRequest, string(b))
		}
		defer db.Close()
		insert, err := db.Query("INSERT INTO service_profile VALUES ( '" + invoiceUUID + "'," +
			"'" + claims["IPAUid"].(string) + "'," +
			"'" + "VM" + "'," +
			"'" + "" + "'," +
			"'" + login(BA).AuthenticatedUser.ID + "'," +
			"NOW()" + "," +
			"NOW() ," +
			"false" + "," +
			"'" + vmname + "'," +
			"'" + invoiceUUID + "' )")
		defer insert.Close()
		if err != nil {
			fmt.Println("Error in addVM: ", err.Error())
		}

	}

	// Start Task
	{

		url := OvirtURL + "/ovirt-engine/api/vms/" + invoiceUUID + "/start"
		method := "POST"
		nicAddress := "172.20.15.251"
		nicMask := "255.255.255.0"
		nicGW := "172.20.15.1"
		__json := fmt.Sprintf(`
{
	"async":"true",
    "use_cloud_init": "true",
    "vm": {
        "initialization": {
            "authorized_ssh_keys": "%s",
            "host_name": "Sassan.local",
            "user_name": "root",
            "root_password": "%s",
            "nic_configurations": {
                "nic_configuration": [
                    {
                        "name": "eth0",
                        "on_boot": "true",
                        "boot_protocol": "static",
                        "ip": {
                            "address": "%s",
                            "netmask": "%s",
                            "gateway": "%s"
                        }
                    }
                ]
            },
            "dns_servers": "172.20.11.11"
        }
    }
}
`, sshKey, rootpass, nicAddress, nicMask, nicGW)
		sha256 := sha256.Sum256([]byte(invoiceUUID))
		var hashChannel = make(chan []byte, 1)
		hashChannel <- sha256[:]
		___json := encrypt(<-hashChannel, __json)
		startVM := addVMTask{
			URL:     url,
			JSON:    ___json,
			Method:  method,
			Headers: nil,
		}
		startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Version", Value: "4"})
		startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Accept", Value: "application/json"})
		startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Content-Type", Value: "application/json"})
		startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Authorization", Value: BA})

		uuid, _ := uuidgen("APIGW-Ovirt-CloudInit")
		__startVM, _ := json.MarshalIndent(startVM, "", "  ")
		//fmt.Println("StartVMHeaders: ", string(__startVMHeaders))
		addTask(uuid, string(__startVM), "", "APIGW", "VM Initialization", invoiceUUID, "1", "0")
	}
	//resp := _response{
	//	Origin:  "ovirt-addvm",
	//	Message: resposeInvoice
	//	Code:    1000,
	//}
	return c.JSON(http.StatusOK, responseInvoiece)
}
func (o ovirt) listVM(c echo.Context) error {
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	_sha256 := sha256.Sum256([]byte(string(claims["name"].(string))))
	var hashChannel_ = make(chan []byte, 1)
	hashChannel_ <- _sha256[:]
	token := decrypt(<-hashChannel_, claims["IPAToken"].(string))
	_BA := strings.Split(token, ";")
	BA := _BA[len(_BA)-2]
	url := OvirtURL + "/ovirt-engine/api/vms"
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)

	if err != nil {
		fmt.Println(err)
	}
	req.Header.Add("Version", "4")
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Authorization", BA)

	res, err := client.Do(req)
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	//fmt.Printf("%s",body)
	//b, _ := json.MarshalIndent(body, "", "  ")
	resp := _response{
		Origin:  "ovirt-listvms",
		Message: string(body),
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	return c.JSON(http.StatusOK, resp)
	//return c.String(http.StatusOK, string(b))
}
func (o ovirt) StartVM(c echo.Context) error {
	vmuuid := c.FormValue("VmUUID")
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	_sha256 := sha256.Sum256([]byte(string(claims["name"].(string))))
	var hashChannel_ = make(chan []byte, 1)
	hashChannel_ <- _sha256[:]
	token := decrypt(<-hashChannel_, claims["IPAToken"].(string))
	_BA := strings.Split(token, ";")
	BA := _BA[len(_BA)-2]
	url := OvirtURL + "/ovirt-engine/api/vms/" + vmuuid + "/start"
	method := "POST"
	__json := "{\"async\":\"true\"}"
	sha256 := sha256.Sum256([]byte(vmuuid))
	var hashChannel = make(chan []byte, 1)
	hashChannel <- sha256[:]
	___json := encrypt(<-hashChannel, __json)
	startVM := addVMTask{
		URL:     url,
		JSON:    ___json,
		Method:  method,
		Headers: nil,
	}
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Version", Value: "4"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Accept", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Content-Type", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Authorization", Value: BA})

	//req.Header.Add("Version", "4")
	//req.Header.Add("Accept", "application/json")
	//req.Header.Add("Authorization", BA)
	//req.Header.Add("Content-Type", "application/json")
	//
	//res, err := client.Do(req)
	//defer res.Body.Close()
	uuid, _ := uuidgen("APIGW-Ovirt")
	__startVM, _ := json.MarshalIndent(startVM, "", "  ")
	//fmt.Println("StartVMHeaders: ", string(__startVMHeaders))
	addTask(uuid, string(__startVM), "", "APIGW", "VM Start", vmuuid, "1", "1")

	resp := _response{
		Origin:  "ovirt-StartVM",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	return c.JSON(http.StatusOK, resp)
	//return c.String(http.StatusOK, string(b))
}
func (o ovirt) StopVM(c echo.Context) error {
	vmuuid := c.FormValue("VmUUID")
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	_sha256 := sha256.Sum256([]byte(string(claims["name"].(string))))
	var hashChannel_ = make(chan []byte, 1)
	hashChannel_ <- _sha256[:]
	token := decrypt(<-hashChannel_, claims["IPAToken"].(string))
	_BA := strings.Split(token, ";")
	BA := _BA[len(_BA)-2]
	url := OvirtURL + "/ovirt-engine/api/vms/" + vmuuid + "/shutdown"
	method := "POST"
	__json := "{\"async\":\"true\"}"
	sha256 := sha256.Sum256([]byte(vmuuid))
	var hashChannel = make(chan []byte, 1)
	hashChannel <- sha256[:]
	___json := encrypt(<-hashChannel, __json)
	startVM := addVMTask{
		URL:     url,
		JSON:    ___json,
		Method:  method,
		Headers: nil,
	}
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Version", Value: "4"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Accept", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Content-Type", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Authorization", Value: BA})

	//req.Header.Add("Version", "4")
	//req.Header.Add("Accept", "application/json")
	//req.Header.Add("Authorization", BA)
	//req.Header.Add("Content-Type", "application/json")
	//
	//res, err := client.Do(req)
	//defer res.Body.Close()
	uuid, _ := uuidgen("APIGW-Ovirt")
	__startVM, _ := json.MarshalIndent(startVM, "", "  ")
	//fmt.Println("StartVMHeaders: ", string(__startVMHeaders))
	addTask(uuid, string(__startVM), "", "APIGW", "VM Start", vmuuid, "1", "1")

	resp := _response{
		Origin:  "ovirt-StopVM",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	return c.JSON(http.StatusOK, resp)
	//return c.String(http.StatusOK, string(b))
}
func (o ovirt) RebootVM(c echo.Context) error {
	vmuuid := c.FormValue("VmUUID")
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	_sha256 := sha256.Sum256([]byte(string(claims["name"].(string))))
	var hashChannel_ = make(chan []byte, 1)
	hashChannel_ <- _sha256[:]
	token := decrypt(<-hashChannel_, claims["IPAToken"].(string))
	_BA := strings.Split(token, ";")
	BA := _BA[len(_BA)-2]
	url := OvirtURL + "/ovirt-engine/api/vms/" + vmuuid + "/reboot"
	method := "POST"
	__json := "{\"async\":\"true\"}"
	sha256 := sha256.Sum256([]byte(vmuuid))
	var hashChannel = make(chan []byte, 1)
	hashChannel <- sha256[:]
	___json := encrypt(<-hashChannel, __json)
	startVM := addVMTask{
		URL:     url,
		JSON:    ___json,
		Method:  method,
		Headers: nil,
	}
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Version", Value: "4"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Accept", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Content-Type", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Authorization", Value: BA})

	//req.Header.Add("Version", "4")
	//req.Header.Add("Accept", "application/json")
	//req.Header.Add("Authorization", BA)
	//req.Header.Add("Content-Type", "application/json")
	//
	//res, err := client.Do(req)
	//defer res.Body.Close()
	uuid, _ := uuidgen("APIGW-Ovirt")
	__startVM, _ := json.MarshalIndent(startVM, "", "  ")
	//fmt.Println("StartVMHeaders: ", string(__startVMHeaders))
	addTask(uuid, string(__startVM), "", "APIGW", "VM Start", vmuuid, "1", "1")

	resp := _response{
		Origin:  "ovirt-RebootVM",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	//return c.String(http.StatusOK, string(b))
	return c.JSON(http.StatusOK, resp)
}
func (o ovirt) PowerOffVM(c echo.Context) error {
	vmuuid := c.FormValue("VmUUID")
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	_sha256 := sha256.Sum256([]byte(string(claims["name"].(string))))
	var hashChannel_ = make(chan []byte, 1)
	hashChannel_ <- _sha256[:]
	token := decrypt(<-hashChannel_, claims["IPAToken"].(string))
	_BA := strings.Split(token, ";")
	BA := _BA[len(_BA)-2]
	url := OvirtURL + "/ovirt-engine/api/vms/" + vmuuid + "/stop"
	method := "POST"
	__json := "{\"async\":\"true\"}"
	sha256 := sha256.Sum256([]byte(vmuuid))
	var hashChannel = make(chan []byte, 1)
	hashChannel <- sha256[:]
	___json := encrypt(<-hashChannel, __json)
	startVM := addVMTask{
		URL:     url,
		JSON:    ___json,
		Method:  method,
		Headers: nil,
	}
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Version", Value: "4"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Accept", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Content-Type", Value: "application/json"})
	startVM.Headers = append(startVM.Headers, TaskHeader{Name: "Authorization", Value: BA})

	//req.Header.Add("Version", "4")
	//req.Header.Add("Accept", "application/json")
	//req.Header.Add("Authorization", BA)
	//req.Header.Add("Content-Type", "application/json")
	//
	//res, err := client.Do(req)
	//defer res.Body.Close()
	uuid, _ := uuidgen("APIGW-Ovirt")
	__startVM, _ := json.MarshalIndent(startVM, "", "  ")
	//fmt.Println("StartVMHeaders: ", string(__startVMHeaders))
	addTask(uuid, string(__startVM), "", "APIGW", "VM Start", vmuuid, "1", "1")

	resp := _response{
		Origin:  "ovirt-PowerOffVM",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	//return c.String(http.StatusOK, string(b))
	return c.JSON(http.StatusOK, resp)
}
func (o ovirt) ResetVM(c echo.Context) error {
	resp := _response{
		Origin:  "ovirt-ResetVM",
		Message: "not implemented",
		Code:    1003,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	return c.JSON(http.StatusOK, resp)
	//return c.String(http.StatusOK, string(b))

}
func (o ovirt) AddNIC(c echo.Context) error {
	resp := _response{
		Origin:  "ovirt-AddNIC",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	//return c.String(http.StatusOK, string(b))
	return c.JSON(http.StatusOK, resp)
}
func (o ovirt) AddDisk(c echo.Context) error {
	resp := _response{
		Origin:  "ovirt-AddDisk",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	//return c.String(http.StatusOK, string(b))
	return c.JSON(http.StatusOK, resp)
}
func (o ovirt) EditVM(c echo.Context) error {
	resp := _response{
		Origin:  "ovirt-EditVM",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	//return c.String(http.StatusOK, string(b))
	return c.JSON(http.StatusOK, resp)
}
func (o ovirt) ResetPassword(c echo.Context) error {
	resp := _response{
		Origin:  "ovirt-ResetPassword",
		Message: "not implemented",
		Code:    1003,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	//return c.String(http.StatusOK, string(b))
	return c.JSON(http.StatusOK, resp)
}
func createVM(invoice_uuid string, apiJson string, uuid string) {
	type AddVMResponse struct {
		NextRunConfigurationExists string `json:"next_run_configuration_exists"`
		NumaTuneMode               string `json:"numa_tune_mode"`
		Status                     string `json:"status"`
		StopTime                   int64  `json:"stop_time"`
		OriginalTemplate           struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"original_template"`
		Template struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"template"`
		Actions struct {
			Link []struct {
				Href string `json:"href"`
				Rel  string `json:"rel"`
			} `json:"link"`
		} `json:"actions"`
		Name        string `json:"name"`
		Description string `json:"description"`
		Comment     string `json:"comment"`
		Href        string `json:"href"`
		ID          string `json:"id"`
		Bios        struct {
			BootMenu struct {
				Enabled string `json:"enabled"`
			} `json:"boot_menu"`
			Type string `json:"type"`
		} `json:"bios"`
		Console struct {
			Enabled string `json:"enabled"`
		} `json:"console"`
		CPU struct {
			Architecture string `json:"architecture"`
			Topology     struct {
				Cores   string `json:"cores"`
				Sockets string `json:"sockets"`
				Threads string `json:"threads"`
			} `json:"topology"`
		} `json:"cpu"`
		Display struct {
			AllowOverride       string `json:"allow_override"`
			CopyPasteEnabled    string `json:"copy_paste_enabled"`
			DisconnectAction    string `json:"disconnect_action"`
			FileTransferEnabled string `json:"file_transfer_enabled"`
			Monitors            string `json:"monitors"`
			SingleQxlPci        string `json:"single_qxl_pci"`
			SmartcardEnabled    string `json:"smartcard_enabled"`
			Type                string `json:"type"`
		} `json:"display"`
		Initialization struct {
			AuthorizedSSHKeys        string `json:"authorized_ssh_keys"`
			CloudInitNetworkProtocol string `json:"cloud_init_network_protocol"`
			CustomScript             string `json:"custom_script"`
			HostName                 string `json:"host_name"`
			NicConfigurations        struct {
			} `json:"nic_configurations"`
			RegenerateSSHKeys string `json:"regenerate_ssh_keys"`
			UserName          string `json:"user_name"`
		} `json:"initialization"`
		Io struct {
			Threads string `json:"threads"`
		} `json:"io"`
		Memory    string `json:"memory"`
		Migration struct {
			AutoConverge string `json:"auto_converge"`
			Compressed   string `json:"compressed"`
			Encrypted    string `json:"encrypted"`
		} `json:"migration"`
		Origin string `json:"origin"`
		Os     struct {
			Boot struct {
				Devices struct {
					Device []string `json:"device"`
				} `json:"devices"`
			} `json:"boot"`
			Type string `json:"type"`
		} `json:"os"`
		Sso struct {
			Methods struct {
				Method []struct {
					ID string `json:"id"`
				} `json:"method"`
			} `json:"methods"`
		} `json:"sso"`
		Stateless string `json:"stateless"`
		Type      string `json:"type"`
		Usb       struct {
			Enabled string `json:"enabled"`
		} `json:"usb"`
		Cluster struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"cluster"`
		Quota struct {
			ID string `json:"id"`
		} `json:"quota"`
		CreationStatus string `json:"creation_status"`
		Link           []struct {
			Href string `json:"href"`
			Rel  string `json:"rel"`
		} `json:"link"`
		CPUShares        string `json:"cpu_shares"`
		CreationTime     int64  `json:"creation_time"`
		DeleteProtected  string `json:"delete_protected"`
		HighAvailability struct {
			Enabled  string `json:"enabled"`
			Priority string `json:"priority"`
		} `json:"high_availability"`
		LargeIcon struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"large_icon"`
		MemoryPolicy struct {
			Ballooning string `json:"ballooning"`
			Guaranteed string `json:"guaranteed"`
			Max        string `json:"max"`
		} `json:"memory_policy"`
		MigrationDowntime  string `json:"migration_downtime"`
		MultiQueuesEnabled string `json:"multi_queues_enabled"`
		RngDevice          struct {
			Source string `json:"source"`
		} `json:"rng_device"`
		SmallIcon struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"small_icon"`
		SoundcardEnabled            string `json:"soundcard_enabled"`
		StartPaused                 string `json:"start_paused"`
		StorageErrorResumeBehaviour string `json:"storage_error_resume_behaviour"`
		TimeZone                    struct {
			Name string `json:"name"`
		} `json:"time_zone"`
		VirtioScsi struct {
			Enabled string `json:"enabled"`
		} `json:"virtio_scsi"`
		CPUProfile struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"cpu_profile"`
	}

	_createVM := AddVMRequest{}
	//fmt.Println(apiJson)
	_err := json.Unmarshal([]byte(apiJson), &_createVM)
	if _err != nil {
		fmt.Println("Error in VMCreation step 1: ", _err.Error())
	}
	addvmresponse := AddVMResponse{}
	var body []byte
	{
		url := _createVM.URL
		method := _createVM.Method
		__json := _createVM.JSON
		client := &http.Client{}
		_json, _ := json.Marshal(__json)
		payload := strings.NewReader(string(_json))
		//payload := __json
		req, err := http.NewRequest(method, url, payload)
		if err != nil {
			fmt.Println("Error in VMCreation  step 2: ", err.Error())
		}
		_headers := _createVM.Headers
		for _, v := range _headers {
			req.Header.Add(v.Name, v.Value)
		}
		if err != nil {
			fmt.Println("Error in VMCreation  step 3: ", err.Error())
		}
		res, err := client.Do(req)
		defer res.Body.Close()
		body, _ = ioutil.ReadAll(res.Body)
	}
	//body := runAPICall(_createVM)
	err := json.Unmarshal(body, &addvmresponse)
	if err != nil {
		fmt.Println("Error in VMCreation  step 4: ", err.Error())
	}
	toggleTask(uuid, 0)
	// find related VMInitialization Task
	//ruuid := ""
	{
		db, err := sql.Open("mysql", MySQLUSER+":"+MySQLPASS+"@tcp(127.0.0.1:3306)/zicloud")
		if err != nil {
			fmt.Println("Error in VMCreation step 3: ", _err.Error())
		}
		//defer db.Close()
		//results, err := db.Query("SELECT uuid as UUID ,task_apiCall as TaskAPICall , cron_expression as CronExpression , related_uuid as Ruuid, type FROM scheduler where  related_invoice=" + invoice_uuid + " and type=1")
		//type Task struct {
		//	UUID           string `json:"uuid"`
		//	TaskAPICall    string `json:"taskapicall"`
		//	Ruuid          string `json:"ruuid"`
		//	CronExpression string `json:"cronexpression"`
		//	Type           string `json:"type"`
		//}
		//for results.Next() {
		//	var res Task
		//	err = results.Scan(&res.UUID, &res.TaskAPICall, &res.CronExpression, &res.Ruuid, &res.Type)
		//	ruuid = res.UUID
		//	break
		//}
		//update UUID and status
		update2, err := db.Query("update service_profile set uuid='" + addvmresponse.ID + "' , active=1 where related_invoice='" + invoice_uuid + "'")
		update, err := db.Query("update scheduler set related_uuid='" + addvmresponse.ID + "' , active=1 where related_uuid='" + invoice_uuid + "' and type=1")
		defer update.Close()
		defer update2.Close()
		//toggleTask(ruuid, 1)
	}

}
func VMInitialization(relatedUuid string, apiCall string, uuid string) {
	iaas := &ovirt{}
	status := iaas.vmStatus(relatedUuid)
	//fmt.Println("VM :", relatedUuid, " is now: ", status)
	if status == "down" {
		//fmt.Println("APICall: ", apiCall)
		startVM := addVMTask{}
		//b, _ := json.Marshal(apiCall)
		_err := json.Unmarshal([]byte(apiCall), &startVM)
		if _err != nil {
			fmt.Println("Error in VMInitialization: ", _err.Error())
		}
		//fmt.Println("calling initialization for VM :", relatedUuid)
		words := strings.Split(startVM.URL, "/")
		//fmt.Println("Invoice : ", words[6])
		_sha256 := sha256.Sum256([]byte(words[6]))
		var hashChannel_ = make(chan []byte, 1)
		hashChannel_ <- _sha256[:]
		//fmt.Println(" startVM.JSON: ", startVM.JSON)
		startVM.JSON = decrypt(<-hashChannel_, startVM.JSON)
		//fmt.Println("decrypted json: ",startVM.JSON)
		startVM.URL = OvirtURL + "/ovirt-engine/api/vms/" + relatedUuid + "/start"
		//fmt.Println("Start URL: ", startVM.URL)
		//fmt.Println("Initialize JSON: ", decrypt(<-hashChannel_, startVM.JSON))
		runAPICall(startVM)
		toggleTask(uuid, 0)
	}
}
func vmStatistics(BA string, VMUUID string) (string, float64, float64) {
	//ram,cpu,storage
	var _disk []string
	{
		type DiskAttachments struct {
			DiskAttachment []struct {
				Active              string `json:"active"`
				Bootable            string `json:"bootable"`
				Interface           string `json:"interface"`
				LogicalName         string `json:"logical_name"`
				PassDiscard         string `json:"pass_discard"`
				ReadOnly            string `json:"read_only"`
				UsesScsiReservation string `json:"uses_scsi_reservation"`
				Disk                struct {
					Href string `json:"href"`
					ID   string `json:"id"`
				} `json:"disk"`
				VM struct {
					Href string `json:"href"`
					ID   string `json:"id"`
				} `json:"vm"`
				Href string `json:"href"`
				ID   string `json:"id"`
			} `json:"disk_attachment"`
		}

		url := OvirtURL + "/ovirt-engine/api/vms/" + VMUUID + "/diskattachments"
		//fmt.Println("Url:" ,url)
		method := "GET"

		client := &http.Client{}
		req, err := http.NewRequest(method, url, nil)

		if err != nil {
			return "", -1, -1
		}
		req.Header.Add("Version", "4")
		req.Header.Add("Accept", "application/json")
		req.Header.Add("Authorization", BA)

		res, err := client.Do(req)
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)
		diskattachments := DiskAttachments{}
		_err := json.Unmarshal(body, &diskattachments)
		if _err != nil {
			fmt.Println("Error in vmStatistics 1: ", _err)
		}
		for _, v := range diskattachments.DiskAttachment {
			url := OvirtURL + "/ovirt-engine/api/disks/" + v.Disk.ID
			type DiskAttachment struct {
				ActualSize      string `json:"actual_size"`
				Alias           string `json:"alias"`
				Backup          string `json:"backup"`
				ContentType     string `json:"content_type"`
				Format          string `json:"format"`
				ImageID         string `json:"image_id"`
				PropagateErrors string `json:"propagate_errors"`
				ProvisionedSize string `json:"provisioned_size"`
				QcowVersion     string `json:"qcow_version"`
				Shareable       string `json:"shareable"`
				Sparse          string `json:"sparse"`
				Status          string `json:"status"`
				StorageType     string `json:"storage_type"`
				TotalSize       string `json:"total_size"`
				WipeAfterDelete string `json:"wipe_after_delete"`
				DiskProfile     struct {
					Href string `json:"href"`
					ID   string `json:"id"`
				} `json:"disk_profile"`
				Quota struct {
					Href string `json:"href"`
					ID   string `json:"id"`
				} `json:"quota"`
				StorageDomains struct {
					StorageDomain []struct {
						Href string `json:"href"`
						ID   string `json:"id"`
					} `json:"storage_domain"`
				} `json:"storage_domains"`
				Actions struct {
					Link []struct {
						Href string `json:"href"`
						Rel  string `json:"rel"`
					} `json:"link"`
				} `json:"actions"`
				Name        string `json:"name"`
				Description string `json:"description"`
				Href        string `json:"href"`
				ID          string `json:"id"`
				Link        []struct {
					Href string `json:"href"`
					Rel  string `json:"rel"`
				} `json:"link"`
			}
			//fmt.Println("Url:" ,url)
			method := "GET"

			client := &http.Client{}
			req, _ := http.NewRequest(method, url, nil)

			//if err != nil {
			//	return "Null"
			//}
			req.Header.Add("Version", "4")
			req.Header.Add("Accept", "application/json")
			req.Header.Add("Authorization", BA)

			res, _ := client.Do(req)
			defer res.Body.Close()
			body, _ := ioutil.ReadAll(res.Body)

			//fmt.Println("full response: ",string(body))
			disk := DiskAttachment{}
			_err := json.Unmarshal(body, &disk)
			if _err != nil {
				fmt.Println("Error in vmStatistics 2 : ", _err)
			}
			_disk = append(_disk, disk.ProvisionedSize)

			//_disk = D_disk + "" + disk.ProvisionedSize+" "
		}

	}
	url := OvirtURL + "/ovirt-engine/api/vms/" + VMUUID + "/statistics"
	//fmt.Println("Url:" ,url)
	method := "GET"

	client := &http.Client{}
	req, err := http.NewRequest(method, url, nil)

	if err != nil {
		return "", -1, -1
	}
	req.Header.Add("Version", "4")
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Authorization", BA)

	res, err := client.Do(req)
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)

	//fmt.Println("full response: ",string(body))
	_vmstatistics := VMStatistics{}
	_err := json.Unmarshal(body, &_vmstatistics)
	if _err != nil {
		fmt.Println("Error in vmStatistics 3: ", _err)
	}
	cpuUUID := _vmstatistics.Statistic[4].ID
	memUsedUUID := _vmstatistics.Statistic[1].ID
	memTotalUUID := _vmstatistics.Statistic[0].ID
	//fmt.Println(memUsedUUID)
	var cpu, memUsed, memTotal string
	type ItemUsage struct {
		Kind   string `json:"kind"`
		Type   string `json:"type"`
		Unit   string `json:"unit"`
		Values struct {
			Value []struct {
				Datum float64 `json:"datum"`
			} `json:"value"`
		} `json:"values"`
		VM struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"vm"`
		Name        string `json:"name"`
		Description string `json:"description"`
		Href        string `json:"href"`
		ID          string `json:"id"`
	}
	{
		url := OvirtURL + "/ovirt-engine/api/vms/" + VMUUID + "/statistics/" + cpuUUID
		//fmt.Println("Url:" ,url)
		method := "GET"

		client := &http.Client{}
		req, err := http.NewRequest(method, url, nil)

		if err != nil {
			return "", -1, -1
		}
		req.Header.Add("Version", "4")
		req.Header.Add("Accept", "application/json")
		req.Header.Add("Authorization", BA)

		res, err := client.Do(req)
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)
		cpuUsage := ItemUsage{}
		_err := json.Unmarshal(body, &cpuUsage)
		if _err != nil {
			fmt.Println("Error in vmStatistics 4 ", _err)
		}
		cpu = fmt.Sprintf("%f", cpuUsage.Values.Value[0].Datum)
	}
	{
		url := OvirtURL + "/ovirt-engine/api/vms/" + VMUUID + "/statistics/" + memUsedUUID
		//fmt.Println("Url:" ,url)
		method := "GET"

		client := &http.Client{}
		req, err := http.NewRequest(method, url, nil)

		if err != nil {
			return "", -1, -1
		}
		req.Header.Add("Version", "4")
		req.Header.Add("Accept", "application/json")
		req.Header.Add("Authorization", BA)

		res, err := client.Do(req)
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)
		memUsage := ItemUsage{}
		_err := json.Unmarshal(body, &memUsage)
		if _err != nil {
			fmt.Println("Error in vmStatistics 5: ", _err)
		}
		memUsed = fmt.Sprintf("%f", memUsage.Values.Value[0].Datum)
	}
	{
		url := OvirtURL + "/ovirt-engine/api/vms/" + VMUUID + "/statistics/" + memTotalUUID
		//fmt.Println("Url:" ,url)
		method := "GET"

		client := &http.Client{}
		req, err := http.NewRequest(method, url, nil)

		if err != nil {
			return "", -1, -1
		}
		req.Header.Add("Version", "4")
		req.Header.Add("Accept", "application/json")
		req.Header.Add("Authorization", BA)

		res, err := client.Do(req)
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)
		memUsage := ItemUsage{}
		_err := json.Unmarshal(body, &memUsage)
		if _err != nil {
			fmt.Println("Error in vmStatistics 6: ", _err)
		}
		memTotal = fmt.Sprintf("%f", memUsage.Values.Value[0].Datum)
	}
	//fmt.Println("CPU:" ,cpu)
	//fmt.Println("MEM:", memUsed)
	//fmt.Println("MEM:", memTotal)
	_memusage, _ := strconv.ParseFloat(memUsed, 32)
	_memtotal, _ := strconv.ParseFloat(memTotal, 32)
	mem := _memusage / _memtotal

	_cpu, _ := strconv.ParseFloat(cpu, 64)
	return strings.Join(_disk, ", "), _cpu, mem

}
func (o ovirt) vmDetails(c echo.Context) error {
	//name,...,traffic,ip,status
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	_sha256 := sha256.Sum256([]byte(string(claims["name"].(string))))
	var hashChannel_ = make(chan []byte, 1)
	hashChannel_ <- _sha256[:]
	token := decrypt(<-hashChannel_, claims["IPAToken"].(string))
	_BA := strings.Split(token, ";")
	BA := _BA[len(_BA)-2]
	uuid := c.FormValue("uuid")
	if len(uuid) < 5 {
		resp := _response{
			Origin:  "AddUser",
			Message: "Missing UUID",
			Code:    1001,
		}
		return c.JSON(http.StatusNotFound, resp)
	}
	type vmStatus struct {
		NextRunConfigurationExists string `json:"next_run_configuration_exists"`
		NumaTuneMode               string `json:"numa_tune_mode"`
		Status                     string `json:"status"`
		StopTime                   int64  `json:"stop_time"`
		OriginalTemplate           struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"original_template"`
		Template struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"template"`
		Actions struct {
			Link []struct {
				Href string `json:"href"`
				Rel  string `json:"rel"`
			} `json:"link"`
		} `json:"actions"`
		Name        string `json:"name"`
		Description string `json:"description"`
		Comment     string `json:"comment"`
		Href        string `json:"href"`
		ID          string `json:"id"`
		Bios        struct {
			BootMenu struct {
				Enabled string `json:"enabled"`
			} `json:"boot_menu"`
			Type string `json:"type"`
		} `json:"bios"`
		CPU struct {
			Architecture string `json:"architecture"`
			Topology     struct {
				Cores   string `json:"cores"`
				Sockets string `json:"sockets"`
				Threads string `json:"threads"`
			} `json:"topology"`
		} `json:"cpu"`
		Display struct {
			AllowOverride       string `json:"allow_override"`
			CopyPasteEnabled    string `json:"copy_paste_enabled"`
			DisconnectAction    string `json:"disconnect_action"`
			FileTransferEnabled string `json:"file_transfer_enabled"`
			Monitors            string `json:"monitors"`
			SingleQxlPci        string `json:"single_qxl_pci"`
			SmartcardEnabled    string `json:"smartcard_enabled"`
			Type                string `json:"type"`
		} `json:"display"`
		Initialization struct {
			AuthorizedSSHKeys        string `json:"authorized_ssh_keys"`
			CloudInitNetworkProtocol string `json:"cloud_init_network_protocol"`
			CustomScript             string `json:"custom_script"`
			HostName                 string `json:"host_name"`
			NicConfigurations        struct {
			} `json:"nic_configurations"`
			RegenerateSSHKeys string `json:"regenerate_ssh_keys"`
			UserName          string `json:"user_name"`
		} `json:"initialization"`
		Io struct {
			Threads string `json:"threads"`
		} `json:"io"`
		Memory    string `json:"memory"`
		Migration struct {
			AutoConverge string `json:"auto_converge"`
			Compressed   string `json:"compressed"`
			Encrypted    string `json:"encrypted"`
		} `json:"migration"`
		Origin string `json:"origin"`
		Os     struct {
			Boot struct {
				Devices struct {
					Device []string `json:"device"`
				} `json:"devices"`
			} `json:"boot"`
			Type string `json:"type"`
		} `json:"os"`
		Sso struct {
			Methods struct {
				Method []struct {
					ID string `json:"id"`
				} `json:"method"`
			} `json:"methods"`
		} `json:"sso"`
		Stateless string `json:"stateless"`
		Type      string `json:"type"`
		Usb       struct {
			Enabled string `json:"enabled"`
		} `json:"usb"`
		Cluster struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"cluster"`
		Quota struct {
			ID string `json:"id"`
		} `json:"quota"`
		Link []struct {
			Href string `json:"href"`
			Rel  string `json:"rel"`
		} `json:"link"`
		CPUShares        string `json:"cpu_shares"`
		CreationTime     int64  `json:"creation_time"`
		DeleteProtected  string `json:"delete_protected"`
		HighAvailability struct {
			Enabled  string `json:"enabled"`
			Priority string `json:"priority"`
		} `json:"high_availability"`
		LargeIcon struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"large_icon"`
		MemoryPolicy struct {
			Ballooning string `json:"ballooning"`
			Guaranteed string `json:"guaranteed"`
			Max        string `json:"max"`
		} `json:"memory_policy"`
		MigrationDowntime  string `json:"migration_downtime"`
		MultiQueuesEnabled string `json:"multi_queues_enabled"`
		PlacementPolicy    struct {
			Affinity string `json:"affinity"`
			Hosts    struct {
				Host []struct {
					Href string `json:"href"`
					ID   string `json:"id"`
				} `json:"host"`
			} `json:"hosts"`
		} `json:"placement_policy"`
		SmallIcon struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"small_icon"`
		StartPaused                 string `json:"start_paused"`
		StorageErrorResumeBehaviour string `json:"storage_error_resume_behaviour"`
		TimeZone                    struct {
			Name string `json:"name"`
		} `json:"time_zone"`
		CPUProfile struct {
			Href string `json:"href"`
			ID   string `json:"id"`
		} `json:"cpu_profile"`
	}
	//url := "https://ovirt-cl.zi-tel.com/ovirt-engine/api/vms/c1a44128-6c6c-406b-99d8-4a68a99380c9"
	url := OvirtURL + "/ovirt-engine/api/vms/" + uuid
	//fmt.Println("Url:" ,url)
	method := "GET"

	client := &http.Client{}
	req, _ := http.NewRequest(method, url, nil)

	//if err != nil {
	//	return "Null"
	//}
	req.Header.Add("Version", "4")
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Authorization", BA)

	res, _ := client.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	//fmt.Println("full response: ",string(body))
	_vmstatus := vmStatus{}
	_err := json.Unmarshal(body, &_vmstatus)
	if _err != nil {
		fmt.Println("Error in vmDetails : ", _err)
	}
	disk, cpu, ram := vmStatistics(BA, uuid)
	type AutoGenerated struct {
		Message struct {
			Disk       string `json:"Disk"`
			Memory     string `json:"Memory"`
			CPU        string `json:"CPU"`
			NetAddress string `json:"NetAddress"`
			Traffic    string `json:"Traffic"`
			Status     string `json:"Status"`
			Name       string `json:"Name"`
		} `json:"message"`
		Origin string `json:"origin"`
		Code   int    `json:"code"`
	}
	resp := AutoGenerated{
		Message: struct {
			Disk       string `json:"Disk"`
			Memory     string `json:"Memory"`
			CPU        string `json:"CPU"`
			NetAddress string `json:"NetAddress"`
			Traffic    string `json:"Traffic"`
			Status     string `json:"Status"`
			Name       string `json:"Name"`
		}{
			Disk:       disk,
			Memory:     fmt.Sprintf("%f", ram),
			CPU:        fmt.Sprintf("%f", cpu),
			NetAddress: "",
			Traffic:    "",
			Status:     _vmstatus.Status,
			Name:       _vmstatus.Name,
		},
		Origin: "vmDetails",
		Code:   1000,
	}
	return c.JSON(http.StatusOK, resp)
	//return _vmstatus.Status, _vmstatus.Name, disk, cpu, ram
}
func (o ovirt) ovirtPayment(c echo.Context) error {
	invoiceUuid := c.FormValue("invoiceUuid")
	db, err := sql.Open("mysql", MySQLUSER+":"+MySQLPASS+"@tcp(127.0.0.1:3306)/zicloud")
	//results, err := db.Query("SELECT uuid as UUID ,task_apiCall as TaskAPICall , cron_expression as CronExpression , related_uuid as Ruuid, type FROM scheduler where active=1")
	///TODO: check duplicate payment confirmation by Invoice table
	if err != nil {
	}
	update, err := db.Query("update scheduler set active='1' where related_uuid='" + invoiceUuid + "' and type=0")
	defer db.Close()
	if err != nil {
	}
	defer update.Close()
	resp := _response{
		Origin:  "ovirt-ovirtPayment",
		Message: "Done",
		Code:    1000,
	}
	//b, _ := json.MarshalIndent(resp, "", "  ")
	//return c.String(http.StatusOK, string(b))
	return c.JSON(http.StatusOK, resp)
}
