/*
Copyright 2014 The Kubernetes Authors.

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 framework

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os/exec"
	"path/filepath"
	"strings"
)

// TODO: These should really just use the GCE API client library or at least use
// better formatted output from the --format flag.

// Returns master & node image string, or error
func lookupClusterImageSources() (string, string, error) {
	// Given args for a gcloud compute command, run it with other args, and return the values,
	// whether separated by newlines, commas or semicolons.
	gcloudf := func(argv ...string) ([]string, error) {
		args := []string{"compute"}
		args = append(args, argv...)
		args = append(args, "--project", TestContext.CloudConfig.ProjectID)
		if TestContext.CloudConfig.MultiMaster {
			args = append(args, "--region", TestContext.CloudConfig.Region)
		} else {
			args = append(args, "--zone", TestContext.CloudConfig.Zone)
		}
		outputBytes, err := exec.Command("gcloud", args...).CombinedOutput()
		str := strings.Replace(string(outputBytes), ",", "\n", -1)
		str = strings.Replace(str, ";", "\n", -1)
		lines := strings.Split(str, "\n")
		if err != nil {
			Logf("lookupDiskImageSources: gcloud error with [%#v]; err:%v", argv, err)
			for _, l := range lines {
				Logf(" > %s", l)
			}
		}
		return lines, err
	}

	// Given a GCE instance, look through its disks, finding one that has a sourceImage
	host2image := func(instance string) (string, error) {
		// gcloud compute instances describe {INSTANCE} --format="get(disks[].source)"
		// gcloud compute disks describe {DISKURL} --format="get(sourceImage)"
		disks, err := gcloudf("instances", "describe", instance, "--format=get(disks[].source)")
		if err != nil {
			return "", err
		} else if len(disks) == 0 {
			return "", fmt.Errorf("instance %q had no findable disks", instance)
		}
		// Loop over disks, looking for the boot disk
		for _, disk := range disks {
			lines, err := gcloudf("disks", "describe", disk, "--format=get(sourceImage)")
			if err != nil {
				return "", err
			} else if len(lines) > 0 && lines[0] != "" {
				return lines[0], nil // break, we're done
			}
		}
		return "", fmt.Errorf("instance %q had no disk with a sourceImage", instance)
	}

	// gcloud compute instance-groups list-instances {GROUPNAME} --format="get(instance)"
	nodeName := ""
	instGroupName := strings.Split(TestContext.CloudConfig.NodeInstanceGroup, ",")[0]
	if lines, err := gcloudf("instance-groups", "list-instances", instGroupName, "--format=get(instance)"); err != nil {
		return "", "", err
	} else if len(lines) == 0 {
		return "", "", fmt.Errorf("no instances inside instance-group %q", instGroupName)
	} else {
		nodeName = lines[0]
	}

	nodeImg, err := host2image(nodeName)
	if err != nil {
		return "", "", err
	}
	frags := strings.Split(nodeImg, "/")
	nodeImg = frags[len(frags)-1]

	// For GKE clusters, MasterName will not be defined; we just leave masterImg blank.
	masterImg := ""
	if masterName := TestContext.CloudConfig.MasterName; masterName != "" {
		img, err := host2image(masterName)
		if err != nil {
			return "", "", err
		}
		frags = strings.Split(img, "/")
		masterImg = frags[len(frags)-1]
	}

	return masterImg, nodeImg, nil
}

func LogClusterImageSources() {
	masterImg, nodeImg, err := lookupClusterImageSources()
	if err != nil {
		Logf("Cluster image sources lookup failed: %v\n", err)
		return
	}
	Logf("cluster-master-image: %s", masterImg)
	Logf("cluster-node-image: %s", nodeImg)

	images := map[string]string{
		"master_os_image": masterImg,
		"node_os_image":   nodeImg,
	}

	outputBytes, _ := json.MarshalIndent(images, "", "  ")
	filePath := filepath.Join(TestContext.ReportDir, "images.json")
	if err := ioutil.WriteFile(filePath, outputBytes, 0644); err != nil {
		Logf("cluster images sources, could not write to %q: %v", filePath, err)
	}
}

func CreateManagedInstanceGroup(size int64, zone, template string) error {
	// TODO(verult): make this hit the compute API directly instead of
	// shelling out to gcloud.
	_, _, err := retryCmd("gcloud", "compute", "instance-groups", "managed",
		"create",
		fmt.Sprintf("--project=%s", TestContext.CloudConfig.ProjectID),
		fmt.Sprintf("--zone=%s", zone),
		TestContext.CloudConfig.NodeInstanceGroup,
		fmt.Sprintf("--size=%d", size),
		fmt.Sprintf("--template=%s", template))
	if err != nil {
		return fmt.Errorf("gcloud compute instance-groups managed create call failed with err: %v", err)
	}
	return nil
}

func GetManagedInstanceGroupTemplateName(zone string) (string, error) {
	// TODO(verult): make this hit the compute API directly instead of
	// shelling out to gcloud. Use InstanceGroupManager to get Instance Template name.

	stdout, _, err := retryCmd("gcloud", "compute", "instance-groups", "managed",
		"list",
		fmt.Sprintf("--filter=name:%s", TestContext.CloudConfig.NodeInstanceGroup),
		fmt.Sprintf("--project=%s", TestContext.CloudConfig.ProjectID),
		fmt.Sprintf("--zones=%s", zone),
	)

	if err != nil {
		return "", fmt.Errorf("gcloud compute instance-groups managed list call failed with err: %v", err)
	}

	templateName, err := parseInstanceTemplateName(stdout)
	if err != nil {
		return "", fmt.Errorf("error parsing gcloud output: %v", err)
	}
	return templateName, nil
}

func DeleteManagedInstanceGroup(zone string) error {
	// TODO(verult): make this hit the compute API directly instead of
	// shelling out to gcloud.
	_, _, err := retryCmd("gcloud", "compute", "instance-groups", "managed",
		"delete",
		fmt.Sprintf("--project=%s", TestContext.CloudConfig.ProjectID),
		fmt.Sprintf("--zone=%s", zone),
		TestContext.CloudConfig.NodeInstanceGroup)
	if err != nil {
		return fmt.Errorf("gcloud compute instance-groups managed delete call failed with err: %v", err)
	}
	return nil
}

func parseInstanceTemplateName(gcloudOutput string) (string, error) {
	const templateNameField = "INSTANCE_TEMPLATE"

	lines := strings.Split(gcloudOutput, "\n")
	if len(lines) <= 1 { // Empty output or only contains column names
		return "", fmt.Errorf("the list is empty")
	}

	// Otherwise, there should be exactly 1 entry, i.e. 2 lines
	fieldNames := strings.Fields(lines[0])
	instanceTemplateColumn := 0
	for instanceTemplateColumn < len(fieldNames) &&
		fieldNames[instanceTemplateColumn] != templateNameField {
		instanceTemplateColumn++
	}

	if instanceTemplateColumn == len(fieldNames) {
		return "", fmt.Errorf("the list does not contain instance template information")
	}

	fields := strings.Fields(lines[1])
	instanceTemplateName := fields[instanceTemplateColumn]

	return instanceTemplateName, nil
}
