package patterns

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"

	"github.com/linuxdeepin/go-lib/log"
)

// TODO: 数据存uadp，目前uadp不完善，存文件里。
const patternDirectory = "/var/lib/dde-daemon/pattern/"

const (
	StateUnset uint8 = iota
	StateReset
	StateSet
)

type mydata struct {
	Enabled bool
	Reset   bool
	Pattern string
}

type DataManager struct {
	username  string
	data      *mydata
	dataMutex sync.Mutex
}

var (
	logger           = log.NewLogger("daemon/accounts/patterns")
	dataManager      = make(map[string]*DataManager)
	dataManagerMutex sync.Mutex
)

func GetDataManager(username string) (*DataManager, error) {
	dataManagerMutex.Lock()
	defer dataManagerMutex.Unlock()

	dm, ok := dataManager[username]
	if ok {
		return dm, nil
	}

	ret := &DataManager{
		username: username,
		data:     &mydata{Enabled: true},
	}
	err := ret.loadFromFileNoLock()
	if err != nil {
		return nil, err
	} else {
		dataManager[username] = ret
	}

	return ret, nil
}

func RemoveDataManager(username string) error {
	dataManagerMutex.Lock()
	defer dataManagerMutex.Unlock()

	dm, ok := dataManager[username]
	if ok {
		delete(dataManager, username)
		return dm.Remove()
	}

	return nil
}

func (m *DataManager) Save() error {
	return m.saveToFile()
}

func (m *DataManager) Load() error {
	return m.loadFromFile()
}

func (m *DataManager) Remove() error {
	return os.RemoveAll(filepath.Join(patternDirectory, m.username))
}

func (m *DataManager) saveToFile() error {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	return m.saveToFileNoLock()
}

func (m *DataManager) saveToFileNoLock() error {
	err := os.MkdirAll(patternDirectory, os.ModePerm)
	if err != nil {
		return err
	}
	data, err := json.Marshal(m.data)
	if err != nil {
		logger.Warning(err)
		return err
	}
	patternFile := filepath.Join(patternDirectory, m.username)
	return ioutil.WriteFile(patternFile, data, 0600)
}

func (m *DataManager) loadFromFile() error {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	return m.loadFromFileNoLock()
}

func (m *DataManager) loadFromFileNoLock() error {
	patternFile := filepath.Join(patternDirectory, m.username)
	data, err := ioutil.ReadFile(patternFile)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		logger.Warning(err)
		return err
	}
	err = json.Unmarshal(data, &m.data)
	if err != nil {
		logger.Warning(err)
		return err
	}

	return nil
}

func (m *DataManager) SetPattern(pattern string) {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	m.data.Pattern = pattern
}

func (m *DataManager) GetPattern() string {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	return m.data.Pattern
}

func (m *DataManager) SetPatternEnabled(enabled bool) {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	m.data.Enabled = enabled
}

func (m *DataManager) GetPatternEnabled() bool {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	return m.data.Enabled
}

func (m *DataManager) SetPatternReset(reset bool) {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	m.data.Reset = reset
}

func (m *DataManager) GetPatternReset() bool {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	return m.data.Reset
}

func (m *DataManager) GetPatternState() byte {
	m.dataMutex.Lock()
	defer m.dataMutex.Unlock()

	ret := StateUnset
	if m.data.Reset {
		ret = StateReset
	}
	if m.data.Pattern != "" {
		ret = StateSet
	}

	return ret
}
