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 }