package operate

import (
	"fmt"
	"io/ioutil"
	"path"

	v1 "github.com/tidbcloud/infra-component/api/v1"
	"sigs.k8s.io/yaml"
)

func readComponentDir(p string) ([]v1.Component, error) {
	files, err := ioutil.ReadDir(p)
	if err != nil {
		return nil, err
	}
	var result []v1.Component
	for _, file := range files {
		filepath := path.Join(p, file.Name())
		c, err := readComponent(filepath)
		if err != nil {
			return nil, err
		}
		result = append(result, c)
	}
	return result, nil
}

func readComponent(p string) (v1.Component, error) {
	var result v1.Component

	content, err := ioutil.ReadFile(p)
	if err != nil {
		return result, err
	}

	err = yaml.Unmarshal(content, &result)
	if err != nil {
		return result, err
	}
	return result, nil
}

func writeComponentDir(dir string, components []v1.Component) error {
	for _, c := range components {
		content, err := yaml.Marshal(c)
		if err != nil {
			return err
		}
		if err := ioutil.WriteFile(path.Join(dir, fmt.Sprintf("%s.yaml", c.Name)), content, 0644); err != nil {
			return err
		}
	}
	return nil
}

func readComponentSetDir(p string) ([]v1.ComponentSet, error) {
	files, err := ioutil.ReadDir(p)
	if err != nil {
		return nil, err
	}
	var result []v1.ComponentSet
	for _, file := range files {
		filepath := path.Join(p, file.Name())
		cs, err := readComponentSet(filepath)
		if err != nil {
			return nil, err
		}
		result = append(result, cs)
	}
	return result, nil
}

func readComponentSet(p string) (v1.ComponentSet, error) {
	var result v1.ComponentSet
	content, err := ioutil.ReadFile(p)
	if err != nil {
		return result, err
	}

	err = yaml.Unmarshal(content, &result)
	if err != nil {
		return result, err
	}
	return result, nil
}

func writeComponentSet(p string, cs v1.ComponentSet) error {
	content, err := yaml.Marshal(cs)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(p, content, 0644)
}

func writeComponentSetDir(dir string, componentsets []v1.ComponentSet) error {
	for _, componentset := range componentsets {
		content, err := yaml.Marshal(componentset)
		if err != nil {
			return err
		}
		if err := ioutil.WriteFile(path.Join(dir, fmt.Sprintf("%s.yaml", componentset.Name)), content, 0644); err != nil {
			return err
		}
	}
	return nil
}
