package blas import ( "context" "os" "path" "strings" "dynatron.me/x/blasphem/internal/common" "dynatron.me/x/blasphem/pkg/auth" "dynatron.me/x/blasphem/pkg/bus" "dynatron.me/x/blasphem/pkg/config" "dynatron.me/x/blasphem/pkg/storage" ) type Core interface { auth.Authenticator bus.Bus storage.Store config.Configured Shutdowner Versioner Component(ComponentKey) Component Components() ComponentStore } var _ Core = (*Blas)(nil) type Shutdowner interface { ShutdownBlas(context.Context) error } type Versioner interface { Version() string } type Blas struct { bus.Bus storage.Store auth.Authenticator Config *config.Config components ComponentStore } type ComponentStore map[ComponentKey]Component func (b *Blas) Version() string { return common.Version } func (b *Blas) Conf() *config.Config { return b.Config } func (b *Blas) ShutdownBlas(ctx context.Context) error { b.Bus.ShutdownBus() b.Store.ShutdownStore() return ctx.Err() } func (b *Blas) ConfigDir() (cd string) { if b.Config.DataDir != nil { cd = *b.Config.DataDir } home, err := os.UserHomeDir() if err != nil { panic(err) } switch { case cd == "": return path.Join(home, "."+common.AppName) case strings.HasPrefix(cd, "~/"): return path.Join(home, cd[2:]) default: return cd } } func (b *Blas) openStore() error { // TODO: based on config, open filestore or db store stor, err := storage.OpenFileStore(b.ConfigDir()) b.Store = stor return err } func (b *Blas) Component(k ComponentKey) Component { c, ok := b.components[k] if !ok { return nil } return c } func (b *Blas) Components() ComponentStore { return b.components } func New(cfg *config.Config) (b *Blas, err error) { b = &Blas{ Bus: bus.New(), Config: cfg, components: make(ComponentStore), } err = b.openStore() if err != nil { return nil, err } b.Authenticator, err = auth.New(b.Store) return b, err }