ppforge/cop/collection.go

117 lines
3.3 KiB
Go

package cop
import (
"encoding/json"
"fmt"
"log"
"os"
"path"
"strings"
"gitea.mmo.to/ppForge/ppforge/globals"
"gitea.mmo.to/ppForge/ppforge/protocol"
)
// GlobalCOP is the global variable holding the protocol collections,
var GlobalCOP *ProtocolCollectionList = &ProtocolCollectionList{[]COPer{}}
// CollectionTypes contains the functions to create actual objects from JSON
var CollectionTypes map[string](func([]byte) (COPer, error))
// InitCollectionTypes initializes the functions for each actual object
func InitCollectionTypes() {
CollectionTypes = map[string]func([]byte) (COPer, error){}
//CollectionTypes["COP"] = COPFromJSON
CollectionTypes["FileCOP"] = FileCOPFromJSON
//CollectionTypes["FileCOPFromGitRemote"] = FileCOPGitRemoteFromJSON
}
// ProtocolCollectionList is a list of all databases, with the most simple interface
type ProtocolCollectionList struct {
PCs []COPer
}
// COPer interface defines the functions a CollectionOfProtocols should have at least.
type COPer interface {
Open(string) error
Close() error
GetProtocols() ([]ProtocolCollectionEntry, error)
AddOrUpdate(*protocol.Protocol) error
Sync() error
Get(string) (*protocol.Protocol, error)
ToJSON() (string, error)
}
// Init initializes the databases, opens the default one and checks for others if available
func init() {
InitCollectionTypes()
Init()
}
// Init the global COP
func Init() {
// initialize default db
fdb := FileCOP{COP{"FileCOP", map[string]ProtocolCollectionEntry{}, false}, globals.CollectionOfProtocolsDir}
err := fdb.Open(globals.CollectionOfProtocolsDir)
if err != nil {
log.Printf("Error opening global COP dir: %v", err)
return
}
err = fdb.Sync()
if err != nil {
log.Printf("Error on initial syncing of the global COP dir: %v", err)
return
}
GlobalCOP.PCs = append(GlobalCOP.PCs, &fdb)
log.Printf("Amount of databases available %d", len(GlobalCOP.PCs))
}
// GetCOP returns the global collection of Protocols
func GetCOP() *ProtocolCollectionList {
return GlobalCOP
}
// Read/WriteCache functions to fullfill [impl->dsn~protocol-collection-cache~0>>utest]
// WriteCache updates the cache file of the available protocols
func (pcl *ProtocolCollectionList) WriteCache() error {
cops := []string{}
for _, pc := range pcl.PCs {
str, err := pc.ToJSON()
if err != nil {
log.Println(err)
}
cops = append(cops, str)
}
data := "{ \"PCs\": [" + strings.Join(cops, ",") + "]}"
err := os.WriteFile(path.Join(globals.CollectionOfProtocolsDir, globals.COPCacheFileName), []byte(data), 0644)
return err
}
// ReadCache reads the cache for display
func (pcl *ProtocolCollectionList) ReadCache() error {
// TODO: Think about if it makes sense to have this function as a member of PCL,
// or if it makes more sense to make this function standalone and return a new PCL?
data, err := os.ReadFile(path.Join(globals.CollectionOfProtocolsDir, globals.COPCacheFileName))
if err != nil {
return err
}
//fmt.Println(string(data))
var raw map[string][]interface{}
err = json.Unmarshal(data, &raw)
PCs := raw
for _, rawcop := range PCs["PCs"] {
cop := rawcop.(map[string]interface{})
coptype := cop["Type"].(string)
copjson, err := json.Marshal(rawcop)
fmt.Println(string(copjson))
if err != nil {
log.Println(err)
}
coper, err := CollectionTypes[coptype](copjson)
pcl.PCs = append(pcl.PCs, coper)
}
fmt.Println(string(data))
return err
}