// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"

	"github.com/golang/protobuf/proto"
	reluipb "golang.org/x/build/cmd/relui/protos"
)

// store is a persistence adapter for saving data.
type store interface {
	AddWorkflow(workflow *reluipb.Workflow) error
	BuildableTask(workflowId, id string) *reluipb.BuildableTask
	Workflow(id string) *reluipb.Workflow
	Workflows() []*reluipb.Workflow
}

var _ store = (*fileStore)(nil)

// newFileStore initializes a fileStore ready for use.
//
// If dir is set to an empty string (""), no data will be saved to disk.
func newFileStore(dir string) *fileStore {
	return &fileStore{
		persistDir: dir,
		ls:         new(reluipb.LocalStorage),
	}
}

// fileStoreName is the name of the data file used by fileStore for persistence.
const fileStoreName = "local_storage.textpb"

// fileStore is a non-durable implementation of store that keeps everything in memory.
type fileStore struct {
	mu sync.Mutex
	ls *reluipb.LocalStorage

	// persistDir is a path to a directory for saving application data in textproto format.
	// Set persistDir to an empty string to disable saving and loading from the filesystem.
	persistDir string
}

// AddWorkflow adds a workflow to the store, persisting changes to disk.
func (f *fileStore) AddWorkflow(w *reluipb.Workflow) error {
	f.mu.Lock()
	f.ls.Workflows = append(f.ls.Workflows, w)
	f.mu.Unlock()
	if err := f.persist(); err != nil {
		return err
	}
	return nil
}

// Workflows returns all reluipb.Workflows stored.
func (f *fileStore) Workflows() []*reluipb.Workflow {
	return f.localStorage().GetWorkflows()
}

// Workflow returns a single reluipb.Workflow found by its id. If it is not found, it returns nil.
func (f *fileStore) Workflow(id string) *reluipb.Workflow {
	for _, w := range f.Workflows() {
		if w.GetId() == id {
			return w
		}
	}
	return nil
}

// BuildableTask returns a single reluipb.BuildableTask found by the reluipb.Workflow id and its id.
// If it is not found, it returns nil.
func (f *fileStore) BuildableTask(workflowId, id string) *reluipb.BuildableTask {
	wf := f.Workflow(workflowId)
	for _, t := range wf.GetBuildableTasks() {
		if t.GetId() == id {
			return t
		}
	}
	return nil
}

// localStorage returns a deep copy of data stored in fileStore.
func (f *fileStore) localStorage() *reluipb.LocalStorage {
	f.mu.Lock()
	defer f.mu.Unlock()
	return proto.Clone(f.ls).(*reluipb.LocalStorage)
}

// persist saves fileStore state to persistDir/fileStoreName.
func (f *fileStore) persist() error {
	if f.persistDir == "" {
		return nil
	}
	if err := os.MkdirAll(f.persistDir, 0755); err != nil {
		return fmt.Errorf("os.MkDirAll(%q, %v) = %w", f.persistDir, 0755, err)
	}
	dst := filepath.Join(f.persistDir, fileStoreName)
	data := []byte(proto.MarshalTextString(f.localStorage()))
	if err := ioutil.WriteFile(dst, data, 0644); err != nil {
		return fmt.Errorf("ioutil.WriteFile(%q, _, %v) = %w", dst, 0644, err)
	}
	return nil
}

// load reads fileStore state from persistDir/fileStoreName.
func (f *fileStore) load() error {
	if f.persistDir == "" {
		return nil
	}
	path := filepath.Join(f.persistDir, fileStoreName)
	b, err := ioutil.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return fmt.Errorf("ioutil.ReadFile(%q) = _, %v", path, err)
	}
	f.mu.Lock()
	defer f.mu.Unlock()
	return proto.UnmarshalText(string(b), f.ls)
}
