package parsemin

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

/*
	Потокобезопасно парсит из строки значение vbyen
*/

// ParseMin -- потокобезопасный парсер vbyen из строки
type ParseMin struct {
	val   int // Значение vbyen
	block sync.RWMutex
}

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

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

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

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

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

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

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