package steps

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/pingcap/log"
	"go.uber.org/zap"
)

type loadResourceFromEnv struct {
	envName string
	target  interface{}
}

func NewLoadResourceFromEnv(envName string, target interface{}) Step {
	return &loadResourceFromEnv{
		envName: envName,
		target:  target,
	}
}

func (s *loadResourceFromEnv) Execute(ctx context.Context) error {
	val, found := os.LookupEnv(s.envName)
	if !found {
		return fmt.Errorf("env name %s not found", s.envName)
	}

	return json.Unmarshal([]byte(val), s.target)
}

func (s *loadResourceFromEnv) String() string {
	return fmt.Sprintf("loadResourceFromEnv(%s) -> %+v", s.envName, s.target)
}

type loadParamFromEnv struct {
	envName string
	target  *string
}

func (l *loadParamFromEnv) String() string {
	return fmt.Sprintf("NewLoadParamFromEnv(%s)", l.envName)
}

func (l *loadParamFromEnv) Execute(ctx context.Context) error {
	v, ok := os.LookupEnv(l.envName)
	if !ok {
		return fmt.Errorf("env name %s not found", l.envName)
	}
	*(l.target) = v
	log.Info("Load Parameter", zap.String(l.envName, v))
	return nil
}

func NewLoadParamFromEnv(envName string, target *string) Step {
	return &loadParamFromEnv{
		envName: envName,
		target:  target,
	}
}

func (b *Builder) LoadParamFromEnv(envName string, target *string) *Builder {
	b.steps = append(b.steps, NewLoadParamFromEnv(envName, target))
	return b
}
