package parsesec

import (
	"fmt"
	"strconv"
	"sync"
)

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

// ParseSec -- парсер секунд
type ParseSec struct {
	val   int
	block sync.RWMutex
}

// NewParseSec -- возвращает новый *ParseSec
func NewParseSec() *ParseSec {
	return &ParseSec{}
}

// Get -- возвращает хранимое значение
func (sf *ParseSec) Get() int {
	sf.block.RLock()
	defer sf.block.RUnlock()
	return sf.val
}

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

// Reset -- сбрасывает значение секунд
func (sf *ParseSec) Reset() {
	sf.block.Lock()
	defer sf.block.Unlock()
	sf.val = 0
}

// Parse -- устанавливает значение секунд
func (sf *ParseSec) Parse(strSec string) error {
	sf.block.Lock()
	defer sf.block.Unlock()
	iSec, err := strconv.Atoi(strSec)
	if err != nil {
		return fmt.Errorf("ParseSec.Parse(): секунды(%v) не число, err=%w", strSec, err)
	}
	if err := sf.set(iSec); err != nil {
		return fmt.Errorf("ParseSec.Parse(): in internal setting, err=\n\t%w", err)
	}
	return nil
}

// Set -- устанавливает целочисленное значение
func (sf *ParseSec) Set(iSec int) error {
	sf.block.Lock()
	defer sf.block.Unlock()
	if err := sf.set(iSec); err != nil {
		return fmt.Errorf("ParseSec.Set(): in internal setting int, err=\n\t%w", err)
	}
	return nil
}

// Внутренняя установка значения секунд
func (sf *ParseSec) set(iSec int) error {
	if !(0 <= iSec && iSec < 60) {
		return fmt.Errorf("ParseSec.set(): секунды(%v) не в диапазоне 0..60", iSec)
	}
	sf.val = iSec
	return nil
}
