package main

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"runtime"

	"github.com/Eriyc/rules_wails/pkg/wails3kit/updates"
	updatesdarwin "github.com/Eriyc/rules_wails/pkg/wails3kit/updates/platform/darwin"
	updateslinux "github.com/Eriyc/rules_wails/pkg/wails3kit/updates/platform/linux"
	updateswindows "github.com/Eriyc/rules_wails/pkg/wails3kit/updates/platform/windows"
	httpmanifest "github.com/Eriyc/rules_wails/pkg/wails3kit/updates/providers/httpmanifest"
	filestore "github.com/Eriyc/rules_wails/pkg/wails3kit/updates/storage/file"
)

const (
	productID      = "com.eriyc.updater-example"
	currentVersion = "0.1.0"
)

type updaterSettings struct {
	ManifestURL string
	Token       string
}

func currentAppDescriptor() (updates.AppDescriptor, error) {
	executablePath, err := os.Executable()
	if err != nil {
		return updates.AppDescriptor{}, err
	}
	workingDirectory, err := os.Getwd()
	if err != nil {
		return updates.AppDescriptor{}, err
	}

	return updates.AppDescriptor{
		ProductID:        productID,
		CurrentVersion:   currentVersion,
		Channel:          updates.ChannelStable,
		OS:               runtime.GOOS,
		Arch:             runtime.GOARCH,
		ExecutablePath:   executablePath,
		Args:             os.Args[1:],
		WorkingDirectory: workingDirectory,
	}, nil
}

func loadUpdaterSettings() updaterSettings {
	settings := updaterSettings{
		ManifestURL: os.Getenv("UPDATER_MANIFEST_URL"),
		Token:       os.Getenv("UPDATER_TOKEN"),
	}
	if settings.ManifestURL == "" {
		settings.ManifestURL = "http://127.0.0.1:18765/manifest.json"
	}
	if settings.Token == "" {
		settings.Token = "test-token"
	}
	return settings
}

func newController(app updates.AppDescriptor) (*updates.Controller, error) {
	settings := loadUpdaterSettings()

	provider, err := httpmanifest.New(httpmanifest.Config{
		ManifestURL: settings.ManifestURL,
		HTTPClient:  http.DefaultClient,
		PrepareRequest: func(request *http.Request) error {
			request.Header.Set("Authorization", "Bearer "+settings.Token)
			return nil
		},
	})
	if err != nil {
		return nil, err
	}

	platformInstaller, err := currentPlatformInstaller()
	if err != nil {
		return nil, err
	}

	return updates.NewController(updates.Config{
		App:        app,
		Provider:   provider,
		Downloader: updates.NewHTTPDownloader(http.DefaultClient),
		Store:      filestore.New(filepath.Join(os.TempDir(), "wails3kit-example", "snapshot.json")),
		Platform:   platformInstaller,
	})
}

func currentPlatformInstaller() (updates.PlatformInstaller, error) {
	switch runtime.GOOS {
	case "darwin":
		return updatesdarwin.New(), nil
	case "linux":
		return updateslinux.New(), nil
	case "windows":
		return updateswindows.New(), nil
	default:
		return nil, fmt.Errorf("unsupported platform: %s", runtime.GOOS)
	}
}
