package repairtime

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

/*
	Потокобезопасное время ожидания до восстановлении ремки
*/

// RepairTime -- потокобезопасное время до восстановления ремки
type RepairTime struct {
	val    int
	valOld int // Старое время до ремки
	block  sync.RWMutex
}

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

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

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

// Set -- устанавливает хранимое время восстановления ремки
func (sf *RepairTime) Set(val string) error {
	sf.block.Lock()
	defer sf.block.Unlock()
	iVal, err := strconv.Atoi(val)
	if err != nil {
		return fmt.Errorf("RepairTime.Set(): val(%v) не число, err=%w", val, err)
	}
	if iVal < 0 {
		return fmt.Errorf("RepairTime.Set(): val(%v) < 0", iVal)
	}
	sf.valOld = sf.val
	sf.val = iVal
	return nil
}

// Dec -- уменьшает на секунду время восстановления
func (sf *RepairTime) Dec() {
	sf.block.Lock()
	defer sf.block.Unlock()
	if sf.val > 0 {
		sf.valOld = sf.val
		sf.val--
	}
}

// IsReady -- возвращает признак готовности восстановления
func (sf *RepairTime) IsReady() bool {
	sf.block.RLock()
	defer sf.block.RUnlock()
	return sf.val == 0
}

// IsChange -- возвращает признак изменения здоровья после присвоения
func (sf *RepairTime) IsChange() bool {
	sf.block.RLock()
	defer sf.block.RUnlock()
	return sf.val == sf.valOld
}
