// Package campaign contains types and functions for the single player campaigns.
package campaign

import (
	"io/ioutil"
	"path/filepath"
	"runtime"
	"sort"

	"git.kirsle.net/SketchyMaze/doodle/assets"
	"git.kirsle.net/SketchyMaze/doodle/pkg/filesystem"
	"git.kirsle.net/SketchyMaze/doodle/pkg/userdir"
)

// List returns the list of available campaign JSONs.
//
// It searches in:
// - The embedded bindata for built-in scenarios
// - Scenarios on disk at the assets/campaigns folder.
// - User-made scenarios at ~/doodle/campaigns.
func List() ([]string, error) {
	var names []string

	// List built-in bindata campaigns.
	if files, err := assets.AssetDir("assets/campaigns"); err == nil {
		names = append(names, files...)
	}

	// WASM: only built-in campaigns, no filesystem access.
	if runtime.GOOS == "js" {
		return names, nil
	}

	// Read system-level doodads first. Ignore errors, if the system path is
	// empty we still go on to read the user directory.
	files, _ := ioutil.ReadDir(filesystem.SystemCampaignsPath)
	for _, file := range files {
		name := file.Name()
		if filepath.Ext(name) == ".json" {
			names = append(names, name)
		}
	}

	// Append user campaigns.
	userFiles, err := userdir.ListCampaigns()
	names = append(names, userFiles...)

	// Deduplicate names.
	var uniq = map[string]interface{}{}
	var result []string
	for _, name := range names {
		if _, ok := uniq[name]; !ok {
			uniq[name] = nil
			result = append(result, name)
		}
	}

	sort.Strings(result)
	return result, err
}
