package tuf

import (
	"bytes"
	"encoding/json"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/flynn/go-tuf/data"
)

func MemoryStore(meta map[string]json.RawMessage, files map[string][]byte) LocalStore {
	if meta == nil {
		meta = make(map[string]json.RawMessage)
	}
	return &memoryStore{
		meta:  meta,
		files: files,
		keys:  make(map[string][]*data.Key),
	}
}

type memoryStore struct {
	meta  map[string]json.RawMessage
	files map[string][]byte
	keys  map[string][]*data.Key
}

func (m *memoryStore) GetMeta() (map[string]json.RawMessage, error) {
	return m.meta, nil
}

func (m *memoryStore) SetMeta(name string, meta json.RawMessage) error {
	m.meta[name] = meta
	return nil
}

func (m *memoryStore) GetStagedTarget(path string) (io.ReadCloser, error) {
	data, ok := m.files[path]
	if !ok {
		return nil, ErrFileNotFound{path}
	}
	return ioutil.NopCloser(bytes.NewReader(data)), nil
}

func (m *memoryStore) Commit(meta map[string]json.RawMessage, targets data.Files) error {
	return nil
}

func (m *memoryStore) GetKeys(role string) ([]*data.Key, error) {
	return m.keys[role], nil
}

func (m *memoryStore) SaveKey(role string, key *data.Key) error {
	if _, ok := m.keys[role]; !ok {
		m.keys[role] = make([]*data.Key, 0)
	}
	m.keys[role] = append(m.keys[role], key)
	return nil
}

func (m *memoryStore) Clean() error {
	return nil
}

func FileSystemStore(dir string) LocalStore {
	return &fileSystemStore{dir}
}

type fileSystemStore struct {
	dir string
}

func (f *fileSystemStore) repoDir() string {
	return filepath.Join(f.dir, "repository")
}

func (f *fileSystemStore) repoTargetsDir() string {
	return filepath.Join(f.repoDir(), "targets")
}

func (f *fileSystemStore) stagedDir() string {
	return filepath.Join(f.dir, "staged")
}

func (f *fileSystemStore) GetMeta() (map[string]json.RawMessage, error) {
	meta := make(map[string]json.RawMessage)
	var err error
	notExists := func(path string) bool {
		_, err := os.Stat(path)
		return os.IsNotExist(err)
	}
	for _, name := range topLevelManifests {
		path := filepath.Join(f.stagedDir(), name)
		if notExists(path) {
			path = filepath.Join(f.repoDir(), name)
			if notExists(path) {
				continue
			}
		}
		meta[name], err = ioutil.ReadFile(path)
		if err != nil {
			return nil, err
		}
	}
	return meta, nil
}

func (f *fileSystemStore) SetMeta(name string, meta json.RawMessage) error {
	if err := f.createDirs(); err != nil {
		return err
	}
	if err := ioutil.WriteFile(filepath.Join(f.stagedDir(), name), prettyJSON(meta), 0644); err != nil {
		return err
	}
	return nil
}

func (f *fileSystemStore) createDirs() error {
	for _, dir := range []string{"keys", "repository", "staged/targets"} {
		if err := os.MkdirAll(filepath.Join(f.dir, dir), 0755); err != nil {
			return err
		}
	}
	return nil
}

func (f *fileSystemStore) GetStagedTarget(path string) (io.ReadCloser, error) {
	file, err := os.Open(filepath.Join(f.stagedDir(), "targets", path))
	if err != nil {
		return nil, err
	}
	return file, nil
}

func (f *fileSystemStore) Commit(meta map[string]json.RawMessage, targets data.Files) error {
	copyToRepo := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() || !info.Mode().IsRegular() {
			return nil
		}
		rel, err := filepath.Rel(f.stagedDir(), path)
		if err != nil {
			return err
		}
		dst := filepath.Join(f.repoDir(), rel)
		if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
			return err
		}
		staged, err := os.Open(path)
		if err != nil {
			return err
		}
		defer staged.Close()
		file, err := os.Create(dst)
		if err != nil {
			return err
		}
		defer file.Close()
		if _, err = io.Copy(file, staged); err != nil {
			return err
		}
		return nil
	}
	needsRemoval := func(path string) bool {
		_, ok := targets[path]
		return !ok
	}
	removeFile := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		rel, err := filepath.Rel(f.repoTargetsDir(), path)
		if err != nil {
			return err
		}
		if !info.IsDir() && needsRemoval(rel) {
			if err := os.Remove(path); err != nil {
				// TODO: log / handle error
			}
			// TODO: remove empty directory
		}
		return nil
	}
	if err := filepath.Walk(f.stagedDir(), copyToRepo); err != nil {
		return err
	}
	if err := filepath.Walk(f.repoTargetsDir(), removeFile); err != nil {
		return err
	}
	return f.Clean()
}

func (f *fileSystemStore) GetKeys(role string) ([]*data.Key, error) {
	files, err := ioutil.ReadDir(filepath.Join(f.dir, "keys"))
	if err != nil {
		return nil, err
	}
	signingKeys := make([]*data.Key, 0, len(files))
	for _, file := range files {
		if !strings.HasPrefix(file.Name(), role) {
			continue
		}
		s, err := os.Open(filepath.Join(f.dir, "keys", file.Name()))
		if err != nil {
			return nil, err
		}
		key := &data.Key{}
		if err := json.NewDecoder(s).Decode(key); err != nil {
			return nil, err
		}
		signingKeys = append(signingKeys, key)
	}
	return signingKeys, nil
}

func (f *fileSystemStore) SaveKey(role string, key *data.Key) error {
	if err := f.createDirs(); err != nil {
		return err
	}
	data, err := json.MarshalIndent(key, "", "  ")
	if err != nil {
		return err
	}
	if err := ioutil.WriteFile(filepath.Join(f.dir, "keys", role+"-"+key.ID()+".json"), prettyJSON(data), 0600); err != nil {
		return err
	}
	return nil
}

func (f *fileSystemStore) Clean() error {
	if err := os.RemoveAll(f.stagedDir()); err != nil {
		return err
	}
	return os.Mkdir(f.stagedDir(), 0755)
}

func prettyJSON(data []byte) []byte {
	var buf bytes.Buffer
	json.Indent(&buf, data, "", "\t")
	buf.WriteByte('\n')
	return buf.Bytes()
}
