/*
* Copyright 2022-present Open Networking Foundation
* 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 commands

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

// DeviceIDForGetAll to get list of device id for GetAll functionality.
func DeviceIDForGetAll() []string {
	// url to fetch device-id list
	baseURL := "http://localhost:8181/device-id-list/"
	vgcClient := http.Client{
		Timeout: time.Second * 2, // Timeout after 2 seconds
	}

	req, err := http.NewRequest(http.MethodGet, baseURL, nil)
	if err != nil {
		//fmt.Errorf("Error sending device id list request : %s", err)
		return nil
	}

	resp, getErr := vgcClient.Do(req)
	if getErr != nil {
		//fmt.Errorf("Error fetching the device id list details: %s", getErr)
		return nil
	}

	if resp.Body != nil {
		defer resp.Body.Close()
	}

	body, readErr := io.ReadAll(resp.Body)
	if readErr != nil {
		//fmt.Errorf("Error while reading device id list details: %s", readErr)
		return nil
	}

	var deviceIDList []string
	marshErr := json.Unmarshal([]byte(body), &deviceIDList)
	if marshErr != nil {
		//fmt.Errorf("Error while unmarshalling device id list details: %s", marshErr)
		return nil
	}

	if len(deviceIDList) == 0 {
		//fmt.Errorf("No device id  found")
		return nil
	}

	return deviceIDList
}

// GetAPIData fetches data for api by url path.
func GetAPIData(path string) ([]byte, error) {
	vgcClient := http.Client{
		Timeout: time.Second * 2, // Timeout after 2 seconds
	}

	req, err := http.NewRequest(http.MethodGet, path, nil)
	if err != nil {
		return nil, fmt.Errorf("Error sending api command request : %s", err)
	}

	resp, getErr := vgcClient.Do(req)
	if getErr != nil {
		return nil, fmt.Errorf("Error fetching the api command output details: %s", getErr)
	}

	if resp.Body != nil {
		defer resp.Body.Close()
	}

	body, readErr := io.ReadAll(resp.Body)
	if readErr != nil {
		return nil, fmt.Errorf("Error while reading api command output details: %s", readErr)
	}

	return body, nil
}

// PutAPIData puts the data to the provided URL.
func PutAPIData(path string, data io.Reader) error {
	vgcClient := http.Client{
		Timeout: time.Second * 2, // Timeout after 2 seconds
	}
	req, err := http.NewRequest(http.MethodPut, path, data)
	if err != nil {
		return fmt.Errorf("Error sending api command request : %s", err)
	}

	_, getErr := vgcClient.Do(req)
	if getErr != nil {
		return fmt.Errorf("Error in set http request: %s", getErr)
	}
	return nil
}
