package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"

	wruntime "github.com/wailsapp/wails/v2/pkg/runtime"
	"github.com/zhyee/zipstream"
)

type MrData struct {
	FormatVersion int
	Game          string
	VersionId     string
	Name          string
	Summary       string
	Files         []MrFile
	Dependencies  map[string]string
}

type MrFile struct {
	Path      string
	Hashes    map[string]string
	Env       map[string]string
	Downloads []string
	FileSize  int
}

type Instance struct {
	InstanceName     string
	ModpackId        string
	ModpackVersion   string
	MinecraftVersion string
	ForgeVersion     string
	NeoForgeVersion  string
	FabricVersion    string
	QuiltVersion     string
	JavaVersion      int
	Libraries        []string
	MainClass        string
}

type InstanceManager struct {
	instances []Instance
	app       *App
}

type mmcpack struct {
	Components []component
}

type component struct {
	Uid     string
	Version string
}

func (i *InstanceManager) SearchInstances() {
	i.instances = []Instance{}
	dir, _ := os.UserConfigDir()
	dir = filepath.Join(dir, "FCLauncher", "instances")
	if _, err := os.Stat(dir); err != nil {
		return
	}
	subdirs, _ := os.ReadDir(dir)
	for _, d := range subdirs {
		if !d.IsDir() {
			continue
		}
		if _, err := os.Stat(filepath.Join(dir, d.Name(), "instance.json")); err != nil {
			continue
		}
		f, _ := os.OpenFile(filepath.Join(dir, d.Name(), "instance.json"), os.O_RDONLY, 0755)
		defer f.Close()
		buff := new(bytes.Buffer)
		io.Copy(buff, f)
		instance := Instance{}
		json.Unmarshal(buff.Bytes(), &instance)
		i.instances = append(i.instances, instance)
	}
}

func (i *InstanceManager) checkJavaVersion(instance Instance) {
	infoPath := filepath.Join(i.app.PrismLauncher.GetInstanceDir(), instance.InstanceName, "mmc-pack.json")
	f, _ := os.OpenFile(infoPath, os.O_RDONLY, 0755)
	defer f.Close()
	dataStr, _ := io.ReadAll(f)
	var data mmcpack
	json.Unmarshal(dataStr, &data)
	mc_version := "0.0"
	for _, comp := range data.Components {
		if comp.Uid == "net.minecraft" {
			mc_version = comp.Version
			break
		}
	}
	fmt.Printf("MC Version: %s", mc_version)
	tokensStr := strings.Split(mc_version, ".")
	tokens := []int{0, 0, 0}
	tokens[0], _ = strconv.Atoi(tokensStr[0])
	tokens[1], _ = strconv.Atoi(tokensStr[1])
	if len(tokensStr) > 2 {
		tokens[2], _ = strconv.Atoi(tokensStr[2])
	}
	javaVer := 8
	if tokens[1] == 17 {
		javaVer = 17
	} else if tokens[1] == 18 || tokens[1] == 19 {
		javaVer = 17
	} else if tokens[1] > 19 {
		if tokens[1] == 20 && tokens[2] < 5 {
			javaVer = 17
		} else {
			javaVer = 21
		}
	}
	fmt.Printf("Req Java Version: %d", javaVer)
	if !i.app.Java.CheckJavaVer(javaVer) {
		i.app.Java.InstallJavaVer(javaVer)
	}

	confPath := filepath.Join(i.app.PrismLauncher.GetInstanceDir(), instance.InstanceName, "instance.cfg")
	f, _ = os.OpenFile(confPath, os.O_RDONLY, 0755)
	defer f.Close()
	buff := new(bytes.Buffer)
	io.Copy(buff, f)
	sc := bufio.NewScanner(buff)
	f, _ = os.OpenFile(confPath, os.O_CREATE|os.O_RDWR, 0755)
	plat := "lin"
	exe := "java"
	if runtime.GOOS == "windows" {
		plat = "win"
		exe = "Java.exe"
	}
	confDir, _ := os.UserConfigDir()
	found := false
	for sc.Scan() {
		line := sc.Text()
		if strings.HasPrefix(line, "JavaPath=") {
			line = fmt.Sprintf("JavaPath=%s/FCLauncher/java/java-%d-%s/bin/%s", strings.ReplaceAll(confDir, "\\", "/"), javaVer, plat, exe)
			found = true
		}
		f.WriteString(line + "\n")
	}
	if !found {
		line := fmt.Sprintf("JavaPath=%s/FCLauncher/java/java-%d-%s/bin/%s", strings.ReplaceAll(confDir, "\\", "/"), javaVer, plat, exe)
		f.WriteString(line + "\n")
		f.WriteString("OverrideJavaLocation=true\nOverrideJava=true\n")
	}
	f.Close()
}

func (i *InstanceManager) InstallModpack(modpack Modpack, instanceName string) {
	i.app.Status(fmt.Sprintf("Installing %s", modpack.Name))
	version := modpack.Versions[len(modpack.Versions)-1]
	dname, _ := os.MkdirTemp("", "fclauncher-*")
	f, _ := os.OpenFile(filepath.Join(dname, instanceName+".mrpack"), os.O_CREATE|os.O_RDWR, 0755)
	defer f.Close()
	HttpDownload(modpack.Id+"/"+version.File, f, i.app.Ctx)
	i.app.PrismLauncher.ImportModpack(f.Name())
	instance := Instance{InstanceName: instanceName, ModpackVersion: version.Version, ModpackId: modpack.Id}
	i.instances = append(i.instances, instance)
	f, _ = os.OpenFile(filepath.Join(i.app.PrismLauncher.GetInstanceDir(), instanceName, "instance.json"), os.O_CREATE|os.O_RDWR, 0755)
	defer f.Close()
	data, _ := json.Marshal(instance)
	f.Write(data)
	i.checkJavaVersion(instance)
	i.SearchInstances()
}

func (i *InstanceManager) InstallVanilla(version string, instanceName string) {
	dir, _ := os.UserConfigDir()
	err := DownloadAssets(version, filepath.Join(dir, "FCLauncher", "assets"), *i.app)
	if err != nil {
		fmt.Printf("Unable to download assets: %s\n", err)
	} else {
		fmt.Printf("Assets Downloaded")
	}
	err = DownloadLibraries(version, filepath.Join(dir, "FCLauncher", "lib"), *i.app)
	if err != nil {
		fmt.Printf("Unable to download libs: %s\n", err)
	} else {
		fmt.Printf("Libs Downloaded")
	}
	InstallNatives(version, filepath.Join(dir, "FCLauncher", "instances", instanceName, "minecraft", "natives"))
	DownloadLoggingConfig(version, filepath.Join(dir, "FCLauncher", "instances", instanceName, "minecraft"))
	err = DownloadExecutable(version, filepath.Join(dir, "FCLauncher", "bin"), *i.app)
	if err != nil {
		fmt.Printf("Unable to download binaries: %s\n", err)
	} else {
		fmt.Printf("Binaries Downloaded")
	}
	metadata, err := GetVersionMetadata(version)
	if err != nil {
		fmt.Printf("unable to pull metadata: %s\n", err)
	}

	err = os.MkdirAll(filepath.Join(dir, "FCLauncher", "instances", instanceName, "minecraft"), 0755)
	if err != nil {
		fmt.Printf("unable to create directory: %s\n", err)
	}
	instance := Instance{InstanceName: instanceName, MinecraftVersion: version, JavaVersion: metadata.JavaVersion.MajorVersion, MainClass: metadata.MainClass}
	for _, lib := range metadata.Libraries {
		instance.Libraries = append(instance.Libraries, lib.Downloads.Artifact.Path)
	}
	data, err := json.Marshal(instance)
	if err != nil {
		fmt.Printf("unable to marshal json data: %s\n", err)
	}
	f, err := os.OpenFile(filepath.Join(dir, "FCLauncher", "instances", instanceName, "instance.json"), os.O_CREATE|os.O_RDWR, 0755)
	if err != nil {
		fmt.Printf("unable to open file: %s\n", err)
	}

	defer f.Close()
	_, err = f.Write(data)
	if err != nil {
		fmt.Printf("unable to write data: %s\n", err)
	}
	i.instances = append(i.instances, instance)

	if !i.app.Java.CheckJavaVer(instance.JavaVersion) {
		i.app.Status(fmt.Sprintf("Installing Java Version %d", instance.JavaVersion))
		i.app.Java.InstallJavaVer(instance.JavaVersion)
	}
	i.SearchInstances()
}

func (i *InstanceManager) GetInstances() []string {
	names := []string{}
	for _, inst := range i.instances {
		names = append(names, inst.InstanceName)
	}
	return names
}

func (i *InstanceManager) CheckUpdate(instance Instance) {
	return
	i.app.Status("Checking for Updates")
	i.app.Modpacks.QuerryModpacks()
	pack := i.app.Modpacks.GetModpack(instance.ModpackId)
	if pack.Versions[len(pack.Versions)-1].Version == instance.ModpackVersion {
		return
	}
	i.app.Status(fmt.Sprintf("Updating %s", instance.InstanceName))
	version := pack.Versions[len(pack.Versions)-1]
	dname, _ := os.MkdirTemp("", "fclauncher-*")
	f, _ := os.OpenFile(filepath.Join(dname, instance.InstanceName+".mrpack"), os.O_CREATE|os.O_RDWR, 0755)
	defer f.Close()
	HttpDownload(pack.Id+"/"+version.File, f, i.app.Ctx)
	i.app.PrismLauncher.ImportModpack(f.Name())
	instance.ModpackVersion = version.Version
	f, _ = os.OpenFile(filepath.Join(i.app.PrismLauncher.GetInstanceDir(), instance.InstanceName, "instance.json"), os.O_CREATE|os.O_RDWR, 0755)
	defer f.Close()
	data, _ := json.Marshal(instance)
	f.Write(data)
	i.checkJavaVersion(instance)
	i.SearchInstances()
}

func (i *InstanceManager) GetInstance(instance string) (Instance, error) {
	instanceObject := Instance{}
	found := false
	for _, inst := range i.instances {
		if inst.InstanceName == instance {
			instanceObject = inst
			found = true
			break
		}
	}
	if !found {
		return Instance{}, fmt.Errorf("unable to find instance %s\n", instance)
	}
	return instanceObject, nil
}

func (i *InstanceManager) LaunchInstance(instance string) {
	i.app.Status(fmt.Sprintf("Launching %s", instance))
	dir, err := os.UserConfigDir()
	if err != nil {
		fmt.Printf("unable to get config directory\n")
	}
	instanceObject, err := i.GetInstance(instance)
	if err != nil {
		fmt.Printf("Unable to find instance\n")
	}
	execName := "java"
	suffix := "lin"
	if runtime.GOOS == "windows" {
		execName = "Javaw.exe"
		suffix = "win"
	}
	dir = filepath.Join(dir, "FCLauncher")
	auth, err := MicrosoftAuth(i.app.Auth)
	if err != nil {
		fmt.Printf("unable to authenticate: %s\n", err)
		return
	}
	args, err := GetOnlineLaunchArgs(instanceObject.MinecraftVersion, instanceObject, filepath.Join(dir, "lib"), filepath.Join(dir, "bin"), filepath.Join(dir, "assets"), filepath.Join(dir, "instances", instance, "minecraft"), auth)
	if err != nil {
		fmt.Printf("unable to get launch args: %s\n", err)
	}
	if instanceObject.ForgeVersion != "" {
		args = append(args, "--launchTarget")
		args = append(args, "forge_client")
	}
	fmt.Printf("Args: %+v", args)
	child := exec.Command(filepath.Join(dir, "java", fmt.Sprintf("java-%d-%s", instanceObject.JavaVersion, suffix), "bin", execName), args...)
	child.Dir = filepath.Join(dir, "instances", instance, "minecraft")
	wruntime.WindowHide(i.app.Ctx)
	data, err := child.CombinedOutput()
	wruntime.WindowShow(i.app.Ctx)
	fmt.Printf("Command Output: %s\n", data)
}

func (i *InstanceManager) InstallFabric(instance string, fabricVersion string) {
	i.app.Status("Installing Fabric")
	instanceObject, err := i.GetInstance(instance)
	if err != nil {
		fmt.Printf("Instance does not exist\n")
	}
	metadata, err := GetFabricMetadata(instanceObject.MinecraftVersion, fabricVersion)
	if err != nil {
		fmt.Printf("unable to get version metadata\n")
	}
client:
	for _, lib := range metadata.LauncherMeta.Libraries.Client {
		tokens := strings.Split(ProcessMavenPath(lib.Name), string(os.PathSeparator))
		pkg := tokens[len(tokens)-2]
		instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name)))
		for ind, path := range instanceObject.Libraries {
			path = strings.ReplaceAll(path, "/", string(os.PathSeparator))
			tokens := strings.Split(path, string(os.PathSeparator))
			if pkg == tokens[len(tokens)-3] {
				instanceObject.Libraries[ind] = filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name))
				fmt.Printf("duplicate library %s\n", pkg)
				continue client
			}
		}
	}
common:
	for _, lib := range metadata.LauncherMeta.Libraries.Common {
		tokens := strings.Split(ProcessMavenPath(lib.Name), string(os.PathSeparator))
		pkg := tokens[len(tokens)-2]
		instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name)))
		for ind, path := range instanceObject.Libraries {
			path = strings.ReplaceAll(path, "/", string(os.PathSeparator))
			tokens := strings.Split(path, string(os.PathSeparator))
			fmt.Printf("Inspecing path %s with %d tokens\n", path, len(tokens))
			if pkg == tokens[len(tokens)-3] {
				instanceObject.Libraries[ind] = filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name))
				fmt.Printf("duplicate library %s\n", pkg)
				continue common
			}
		}
	}
	instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(metadata.Loader.Maven), ProcessMavenFilename(metadata.Loader.Maven)))

	instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(metadata.Intermediary.Maven), ProcessMavenFilename(metadata.Intermediary.Maven)))

	instanceObject.MainClass = metadata.LauncherMeta.MainClass["client"]
	instanceObject.FabricVersion = fabricVersion
	dir, _ := os.UserConfigDir()
	InstallFabricLibs(instanceObject.MinecraftVersion, fabricVersion, filepath.Join(dir, "FCLauncher", "lib"), i.app)
	f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "instances", instance, "instance.json"), os.O_CREATE|os.O_RDWR, 0755)
	data, _ := json.Marshal(instanceObject)
	defer f.Close()
	f.Write(data)
	for ind, inst := range i.instances {
		if inst.InstanceName == instance {
			i.instances[ind] = instanceObject
			break
		}
	}
}

func (i *InstanceManager) InstallQuilt(instance string, quiltVersion string) {
	i.app.Status("Installing Quilt")
	instanceObject, err := i.GetInstance(instance)
	if err != nil {
		fmt.Printf("Instance does not exist\n")
	}
	metadata, err := GetQuiltMetadata(instanceObject.MinecraftVersion, quiltVersion)
	if err != nil {
		fmt.Printf("unable to get version metadata\n")
	}
client:
	for _, lib := range metadata.LauncherMeta.Libraries.Client {
		tokens := strings.Split(ProcessMavenPath(lib.Name), string(os.PathSeparator))
		pkg := tokens[len(tokens)-2]
		instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name)))
		for ind, path := range instanceObject.Libraries {
			path = strings.ReplaceAll(path, "/", string(os.PathSeparator))
			tokens := strings.Split(path, string(os.PathSeparator))
			if pkg == tokens[len(tokens)-3] {
				instanceObject.Libraries[ind] = filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name))
				fmt.Printf("duplicate library %s\n", pkg)
				continue client
			}
		}
	}
common:
	for _, lib := range metadata.LauncherMeta.Libraries.Common {
		tokens := strings.Split(ProcessMavenPath(lib.Name), string(os.PathSeparator))
		pkg := tokens[len(tokens)-2]
		instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name)))
		for ind, path := range instanceObject.Libraries {
			path = strings.ReplaceAll(path, "/", string(os.PathSeparator))
			tokens := strings.Split(path, string(os.PathSeparator))
			if pkg == tokens[len(tokens)-3] {
				instanceObject.Libraries[ind] = filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name))
				fmt.Printf("duplicate library %s\n", pkg)
				continue common
			}
		}
	}
	instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(metadata.Loader.Maven), ProcessMavenFilename(metadata.Loader.Maven)))

	instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(metadata.Intermediary.Maven), ProcessMavenFilename(metadata.Intermediary.Maven)))

	instanceObject.Libraries = append(instanceObject.Libraries, filepath.Join(ProcessMavenPath(metadata.Hashed.Maven), ProcessMavenFilename(metadata.Hashed.Maven)))

	instanceObject.MainClass = metadata.LauncherMeta.MainClass["client"]
	instanceObject.QuiltVersion = quiltVersion
	dir, _ := os.UserConfigDir()
	InstallQuiltLibs(instanceObject.MinecraftVersion, quiltVersion, filepath.Join(dir, "FCLauncher", "lib"), i.app)
	f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "instances", instance, "instance.json"), os.O_CREATE|os.O_RDWR, 0755)
	data, _ := json.Marshal(instanceObject)
	defer f.Close()
	f.Write(data)
	for ind, inst := range i.instances {
		if inst.InstanceName == instance {
			i.instances[ind] = instanceObject
			break
		}
	}
}

func (i *InstanceManager) InstallForge(instance string, forgeVersion string) {
	instanceObject, err := i.GetInstance(instance)
	if err != nil {
		fmt.Printf("Unable to find instance: %s\n", err)
	}
	installData, err := GetForgeInstallData(instanceObject.MinecraftVersion, forgeVersion)
	if err != nil {
		fmt.Printf("Unable to get install data: %s\n", err)
	}
	dir, _ := os.UserConfigDir()
	InstallForgeLibs(instanceObject.MinecraftVersion, forgeVersion, filepath.Join(dir, "FCLauncher", "lib"))
	instanceObject.ForgeVersion = forgeVersion
outer:
	for _, lib := range installData.Libraries {
		tokens := strings.Split(lib.Downloads.Artifact.Path, string(os.PathSeparator))
		pkg := tokens[len(tokens)-2]
		instanceObject.Libraries = append(instanceObject.Libraries, lib.Downloads.Artifact.Path)
		for ind, path := range instanceObject.Libraries {
			tokens := strings.Split(path, string(os.PathSeparator))
			if pkg == tokens[len(tokens)-3] {
				instanceObject.Libraries[ind] = filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name))
				fmt.Printf("duplicate library %s\n", pkg)
				continue outer
			}
		}
	}
	instanceObject.MainClass = installData.MainClass

	f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "instances", instance, "instance.json"), os.O_CREATE|os.O_RDWR, 0755)
	data, _ := json.Marshal(instanceObject)
	defer f.Close()
	f.Write(data)
	for ind, inst := range i.instances {
		if inst.InstanceName == instance {
			i.instances[ind] = instanceObject
			break
		}
	}

}

func (i *InstanceManager) ImportModpack(modpack Modpack, name string) {
	i.app.Status(fmt.Sprintf("Downloading %s", modpack.Name))
	buff := new(bytes.Buffer)
	err := HttpDownload(filepath.Join(modpack.Id, modpack.Versions[len(modpack.Versions)-1].File), buff, i.app.Ctx)
	if err != nil {
		fmt.Printf("Unable to download modpack file: %s\n", err)
		return
	}
	i.ImportMrpack(buff, name)

}

func (i *InstanceManager) ImportMrpack(data io.Reader, name string) {
	dir, _ := os.UserConfigDir()
	InstancePath := filepath.Join(dir, "FCLauncher", "instances", name, "minecraft")
	zr := zipstream.NewReader(data)
	mrdata := MrData{}
	i.app.Status("Unpacking modpack File")
	for {
		entry, err := zr.GetNextEntry()
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Printf("Error unpacking modpack file: %s\n", err)
			break
		}
		if entry.Name == "modrinth.index.json" {
			i.app.Status("Loading metadata")
			file, _ := entry.Open()
			data, _ := io.ReadAll(file)
			json.Unmarshal(data, &mrdata)
		} else {
			i.app.Status(fmt.Sprintf("Unpacking %s", entry.Name))
			prefix := strings.Split(entry.Name, "/")[0]
			if prefix == "overrides" || prefix == "client-overrides" {
				path := strings.SplitN(entry.Name, "/", 2)[1]
				if entry.IsDir() {
					fmt.Printf("creating directory %s\n", filepath.Join(InstancePath, path))
					if _, err := os.Stat(filepath.Join(InstancePath, path)); err != nil {
						os.MkdirAll(filepath.Join(InstancePath, path), 0755)
					}
				} else {
					zf, _ := entry.Open()
					defer zf.Close()
					fileDir := ""
					tokens := strings.Split(path, "/")
					for ind, token := range tokens {
						if ind != len(tokens)-1 {
							fileDir = filepath.Join(fileDir, token)
						}
					}
					fmt.Printf("creating directory %s\n", filepath.Join(InstancePath, fileDir))
					if _, err := os.Stat(filepath.Join(InstancePath, fileDir)); err != nil {
						os.MkdirAll(filepath.Join(InstancePath, fileDir), 0755)
					}
					file, _ := os.OpenFile(filepath.Join(InstancePath, path), os.O_CREATE|os.O_RDWR, 0755)
					defer file.Close()
					io.Copy(file, zf)
				}
			}
		}
	}
	i.InstallVanilla(mrdata.Dependencies["minecraft"], name)
	if mrdata.Dependencies["forge"] != "" {
		fmt.Printf("Forge not implemented!")
		//implement forge
	} else if mrdata.Dependencies["neoforge"] != "" {
		fmt.Printf("Neoforge not implemented!")
		//implement neoforge
	} else if mrdata.Dependencies["fabric-loader"] != "" {
		i.InstallFabric(name, mrdata.Dependencies["fabric-loader"])
	} else if mrdata.Dependencies["quilt-loader"] != "" {
		i.InstallQuilt(name, mrdata.Dependencies["quilt-loader"])
	}
	i.app.Status("Downloading Mods")
	for _, f := range mrdata.Files {
		fmt.Printf("Downloading %s\n", f.Path)
		i.app.Status(fmt.Sprintf("Downloading %s", f.Path))
		resp, err := http.Get(f.Downloads[0])
		if err != nil {
			fmt.Printf("Unable to download file %s\n", err)
			continue
		}
		defer resp.Body.Close()
		buff := new(bytes.Buffer)
		downloaded := 0
		for {
			count, err := io.CopyN(buff, resp.Body, BlockSize)
			if err == io.EOF {
				downloaded += int(count)
				break
			}
			if err != nil {
				fmt.Printf("Error Downloading libs: %e\n", err)
				return
			}
			downloaded += int(count)
			wruntime.EventsEmit(i.app.Ctx, "download", downloaded, f.FileSize)
		}
		fileDir := ""
		tokens := strings.Split(f.Path, "/")
		for ind, token := range tokens {
			if ind != len(tokens)-1 {
				fileDir = filepath.Join(fileDir, token)
			}
		}
		if _, err := os.Stat(filepath.Join(InstancePath, fileDir)); err != nil {
			os.MkdirAll(filepath.Join(InstancePath, fileDir), 0755)
		}
		file, _ := os.OpenFile(filepath.Join(InstancePath, f.Path), os.O_CREATE|os.O_RDWR, 0755)
		defer file.Close()
		io.Copy(file, buff)
		wruntime.EventsEmit(i.app.Ctx, "download_complete")
	}
}

func (i *InstanceManager) OpenInstanceFolder(instance string) {
	_, err := i.GetInstance(instance)
	if err != nil {
		fmt.Printf("Instance does not exist\n")
	}
	dir, _ := os.UserConfigDir()
	openbrowser(filepath.Join(dir, "FCLauncher", "instances", instance, "minecraft"))
}

func (i *InstanceManager) DeleteInstance(instance string) {
	_, err := i.GetInstance(instance)
	if err != nil {
		fmt.Printf("Instance does not exist\n")
		return
	}
	dir, _ := os.UserConfigDir()
	os.RemoveAll(filepath.Join(dir, "FCLauncher", "instances", instance))
	i.SearchInstances()
}
