// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.

package resource

import (
	"context"
	"fmt"
	"gopkg.in/yaml.v3"
	_ "log"
	"net/url"
	_ "os"
	_ "os/exec"
	"path/filepath"
_	"strings"
	"io"
	"gitea.rosskeen.house/rosskeen.house/machine"
)

type Exec struct {
	Id     string `yaml:"id" json:"id"`
	CreateTemplate Command `yaml:"create" json:"create"`
	ReadTemplate Command `yaml:"read" json:"read"`
	UpdateTemplate Command `yaml:"update" json:"update"`
	DeleteTemplate Command `yaml:"delete" json:"delete"`

	// state attributes
	State string `yaml:"state"`
}

func init() {
	ResourceTypes.Register("exec", func(u *url.URL) Resource {
		x := NewExec()
		return x
	})
}

func NewExec() *Exec {
	return &Exec{}
}

func (x *Exec) Clone() Resource {
	return &Exec {
		Id: x.Id,
		CreateTemplate: x.CreateTemplate,
		ReadTemplate: x.ReadTemplate,
		UpdateTemplate: x.UpdateTemplate,
		DeleteTemplate: x.DeleteTemplate,
		State: x.State,
	}
}

func (x *Exec) StateMachine() machine.Stater {
	return ProcessMachine()
}

func (x *Exec) URI() string {
	return fmt.Sprintf("exec://%s", x.Id)
}

func (x *Exec) SetURI(uri string) error {
	resourceUri, e := url.Parse(uri)
	if e == nil {
		if resourceUri.Scheme == "exec" {
			x.Id = filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())
		} else {
			e = fmt.Errorf("%w: %s is not an exec resource ", ErrInvalidResourceURI, uri)
		}
	}
	return e
}

func (x *Exec) ResolveId(ctx context.Context) string {
	return ""
}

func (x *Exec) Validate() error {
	return fmt.Errorf("failed")
}

func (x *Exec) Apply() error {
	return nil
}

func (x *Exec) Load(r io.Reader) error {
	c := NewYAMLDecoder(r)
	return c.Decode(x)
}

func (x *Exec) LoadDecl(yamlResourceDeclaration string) error {
	c := NewYAMLStringDecoder(yamlResourceDeclaration)
	return c.Decode(x)
}

func (x *Exec) Type() string { return "exec" }

func (x *Exec) Read(ctx context.Context) ([]byte, error) {
	return yaml.Marshal(x)
}
