package parse_sec

import (
	"fmt"
	"strconv"
	"sync"
	"wartank/pkg/alias"
	"wartank/pkg/types"
)

/*
	Парсер секунд
*/

// ПарсерСекунд -- парсер секунд
type ПарсерСекунд struct {
	знач alias.Сек
	блок sync.RWMutex
}

// НовПарсерСекунд -- возвращает новый *ParseSec
func НовПарсерСекунд() *ПарсерСекунд {
	сам := &ПарсерСекунд{}
	_ = types.ИПарсерСек(сам)
	return сам
}

// ПолучМилСек -- возвращает число милСек в хранимых секундах
func (сам *ПарсерСекунд) ПолучМилСек() alias.МилСек {
	return alias.МилСек(сам.знач * 1_000)
}

// Получ -- возвращает хранимое значение секунд
func (сам *ПарсерСекунд) Получ() alias.Сек {
	сам.блок.RLock()
	defer сам.блок.RUnlock()
	return сам.знач
}

// String -- возвращает строковое значение секунд
func (сам *ПарсерСекунд) String() string {
	сам.блок.RLock()
	defer сам.блок.RUnlock()
	res := fmt.Sprintf("%02d", сам.знач)
	return res
}

// Сброс -- сбрасывает значение секунд
func (сам *ПарсерСекунд) Сброс() {
	сам.блок.Lock()
	defer сам.блок.Unlock()
	сам.знач = 0
}

// Уст -- устанавливает значение секунд
func (сам *ПарсерСекунд) Уст(стрСек alias.Время) error {
	сам.блок.Lock()
	defer сам.блок.Unlock()
	_цСек, err := strconv.Atoi(string(стрСек))
	if err != nil {
		return fmt.Errorf("ПарсерСекунд.Уст(): секунды(%v) не число, ош=\n\t%w", стрСек, err)
	}
	цСек := alias.Сек(_цСек)
	if err := сам.уст(цСек); err != nil {
		return fmt.Errorf("ПарсерСекунд.Уст(): при внутренней установке, ош=\n\t%w", err)
	}
	return nil
}

// УстСек -- устанавливает хранимое значение секунд
func (сам *ПарсерСекунд) УстСек(цСек alias.Сек) error {
	сам.блок.Lock()
	defer сам.блок.Unlock()
	if ош := сам.уст(цСек); ош != nil {
		return fmt.Errorf("ПарсерСекунд.Уст(): при установке числа секунд, ош=\n\t%w", ош)
	}
	return nil
}

// Внутренняя установка значения секунд
func (сам *ПарсерСекунд) уст(цСек alias.Сек) error {
	if цСек >= 60 {
		return fmt.Errorf("ПарсерСекунд.уст(): секунды(%v) не в диапазоне 0..60", цСек)
	}
	сам.знач = цСек
	return nil
}
