package main

import (
	"encoding/json"
	"errors"
	"os"
	"path/filepath"
)

// ПРИМЕЧАНИЕ: как и "Трупные батончики", "Странник" сохраняется на
// диск — это открытая, долгоиграющая карьера без фиксированного
// конца партии, и жалко было бы сбрасывать прогресс при каждом
// выходе в меню. Остальные игры коллекции по-прежнему не сохраняются
// между запусками.

var ErrWayfarerNoSave = errors.New("файл сохранения не найден")

func wayfarerSavePath() (string, error) {
	dir, err := os.UserConfigDir()
	if err != nil {
		return "", err
	}
	return filepath.Join(dir, "go-games-collection", "wayfarer_save.json"), nil
}

// SaveWayfarerShip сохраняет текущее состояние карьеры на диск.
func SaveWayfarerShip(s *WayfarerShip) error {
	path, err := wayfarerSavePath()
	if err != nil {
		return err
	}
	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
		return err
	}
	data, err := json.MarshalIndent(s, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(path, data, 0o644)
}

// LoadWayfarerShip загружает сохранённую карьеру с диска. Возвращает
// ErrWayfarerNoSave, если файла нет — вызывающий код должен в этом
// случае начать новую карьеру.
func LoadWayfarerShip() (*WayfarerShip, error) {
	path, err := wayfarerSavePath()
	if err != nil {
		return nil, err
	}
	data, err := os.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, ErrWayfarerNoSave
		}
		return nil, err
	}
	var s WayfarerShip
	if err := json.Unmarshal(data, &s); err != nil {
		return nil, err
	}
	if s.Equipment == nil {
		s.Equipment = map[WayfarerEquipment]bool{}
	}
	if s.Visited == nil {
		s.Visited = map[WayfarerSystemID]bool{}
	}
	if s.CompletedQuests == nil {
		s.CompletedQuests = map[string]bool{}
	}
	if s.FailedQuests == nil {
		s.FailedQuests = map[string]bool{}
	}
	if s.MissileCapacity == 0 {
		// поле появилось уже после того, как некоторые сохранения были
		// созданы — без этой миграции у них "нет свободных слотов"
		// навсегда, хотя ракет на борту нет вовсе (0 >= 0)
		s.MissileCapacity = 2
	}
	if len(s.Cargo) < len(WayfarerCommodities) {
		grown := make([]int, len(WayfarerCommodities))
		copy(grown, s.Cargo)
		s.Cargo = grown
	}
	return &s, nil
}

// DeleteWayfarerSave удаляет файл сохранения (используется при
// гибели корабля без спасательной капсулы — карьера окончена
// безвозвратно, начинать заново нужно с чистого листа).
func DeleteWayfarerSave() error {
	path, err := wayfarerSavePath()
	if err != nil {
		return err
	}
	err = os.Remove(path)
	if err != nil && !os.IsNotExist(err) {
		return err
	}
	return nil
}
