package parser

import (
	"encoding/json"
	"github.com/go-resty/resty/v2"
	"io"
	"os"
)

type mergeAble interface {
	Version() string
}

func readAndMergeConfig[T mergeAble](remote, local string) (*T, error) {
	var rm T
	if remote != "" {
		rsp, err := resty.New().R().
			SetDoNotParseResponse(true).
			Get(remote)
		if err != nil {
			return nil, err
		}
		defer rsp.RawBody().Close()
		err = json.NewDecoder(rsp.RawBody()).Decode(&rm)
		if err != nil {
			return nil, err
		}
	}
	f, err := os.Open(local)
	if err != nil {
		if os.IsNotExist(err) &&
			rm.Version() != "" {
			return nil, nil
		}
		return nil, err
	}
	defer f.Close()
	var lo T
	err = json.NewDecoder(f).Decode(&lo)
	if err != nil {
		return nil, err
	}
	if rm.Version() == "" {
		return &lo, nil
	}
	if lo.Version() != rm.Version() {
		return &rm, nil
	}
	return &lo, nil
}

func (p *Parser) mergeOutbound() error {
	if p.Outbound.RemoteOutboundPath == "" {
		return nil
	}
	var remote []byte
	rsp, err := resty.New().R().
		Get(p.Outbound.RemoteOutboundPath)
	if err != nil {
		return err
	}
	remote = rsp.Body()
	f, err := os.OpenFile(p.Outbound.RemoteOutboundPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0744)
	if err != nil {
		return err
	}
	defer f.Close()
	local, err := io.ReadAll(f)
	if err != nil {
		return err
	}
	if Sum256(remote) == Sum256(local) {
		return nil
	}
	f.Truncate(0)
	f.Seek(0, 0)
	_, err = f.Write(remote)
	if err != nil {
		return err
	}
	return nil
}
