package clientcmd

import (
	"fmt"

	clientconfig "github.com/deranjer/gvc/client/clientconfig"
	"github.com/deranjer/gvc/common"
	"github.com/deranjer/store"
	"github.com/go-resty/resty/v2"
)

// RefreshContent gets all the new file locks and updated pulls from the server (like git fetch)
func RefreshContent(conf *clientconfig.Gvcconfig, repoName string) error { //TODO: need to change command to be able to target user specified servers
	connectionString, err := FindServer("", conf.CurrentBranch, conf)
	var refreshResult common.RepoRefreshRequest
	if err != nil {
		return err
	}
	client := resty.New()
	resp, err := client.R().
		SetPathParams(map[string]string{
			"repoName": repoName,
		}).
		SetResult(&refreshResult).                         // Automatically unmarshal the JSON response to our struct
		Get(connectionString + "/refresh/" + "{repoName}") //creating the full string to get info
	if err != nil {
		return fmt.Errorf("error connecting to server at: %s: error was: %s", connectionString, err)
	}
	if resp.IsError() {
		if resp.StatusCode() == 404 {
			return fmt.Errorf("error: repo %s was not found on server, 404: %s", repoName, resp.Request.URL)
		}
		return fmt.Errorf("response not a success: %d: connection URL: %s", resp.StatusCode(), resp.Request.URL)
	}
	//fmt.Println(resp)
	fmt.Printf("%+v\n", refreshResult)
	fmt.Println("Merging server config with local config...")
	// TODO: Save a backup of the config in case we need to roll back
	// TODO: Before merging check to make sure the slices aren't already the same
	conf.Locked = refreshResult.Locked // Overwriting locks on client since server is authoritative on locks
	fmt.Println("Replaced client locked with server locked...")
	// Now merging the structs where the user might have customized for their environment
	conf.NoCompress.Exts = append(conf.NoCompress.Exts, refreshResult.NoCompress.Exts...)
	conf.NoCompress.Files = append(conf.NoCompress.Files, refreshResult.NoCompress.Files...)
	conf.NoCompress.Folders = append(conf.NoCompress.Folders, refreshResult.NoCompress.Folders...)
	conf.Ignores.Exts = append(conf.Ignores.Exts, refreshResult.Ignores.Exts...)
	conf.Ignores.Files = append(conf.Ignores.Files, refreshResult.Ignores.Files...)
	conf.Ignores.Folders = append(conf.Ignores.Folders, refreshResult.Ignores.Folders...)
	// And then purging the duplicates using a map in case there are very large slices
	conf.NoCompress.Exts = common.RemoveDuplicatesFromSlice(conf.NoCompress.Exts)
	conf.NoCompress.Files = common.RemoveDuplicatesFromSlice(conf.NoCompress.Files)
	conf.NoCompress.Folders = common.RemoveDuplicatesFromSlice(conf.NoCompress.Folders)
	conf.Ignores.Exts = common.RemoveDuplicatesFromSlice(conf.Ignores.Exts)
	conf.Ignores.Files = common.RemoveDuplicatesFromSlice(conf.Ignores.Files)
	conf.Ignores.Folders = common.RemoveDuplicatesFromSlice(conf.Ignores.Folders)
	fmt.Println("Joined and purged duplicates for Ignore and NoCompress...")
	conf.RemoteBranches = refreshResult.Branches
	fmt.Println("updated remote branches...")
	// TODO Update Commits
	err = store.Save(ConfigPath, &conf)
	if err != nil {
		return fmt.Errorf("unable to save refreshed config to file: %s", err)
	}
	return nil
}
