package onescli

import (
	"context"
	"fmt"
	"sync"

	"github.com/tidbcloud/devops/pkg/infra/clients/onescli/api"
)

type ProjectCache struct {
	mu            sync.RWMutex
	nameToProject map[string]*api.Project
	client        *client
}

func (c *ProjectCache) GetByName(ctx context.Context, name string) (*api.Project, error) {
	c.mu.RLock()
	if c.nameToProject != nil {
		project, ok := c.nameToProject[name]
		c.mu.RUnlock()
		if ok {
			return project, nil
		}

		return nil, fmt.Errorf("project %s not found", name)
	}
	c.mu.RUnlock()

	c.mu.Lock()
	defer c.mu.Unlock()

	if c.nameToProject == nil {
		if err := c.sync(ctx); err != nil {
			return nil, err
		}
	}

	if project, ok := c.nameToProject[name]; ok {
		return project, nil
	}

	return nil, fmt.Errorf("project %s not found", name)
}

func (c *ProjectCache) sync(ctx context.Context) error {
	projects, err := c.client.ListProjects(ctx)
	if err != nil {
		return err
	}

	if c.nameToProject == nil {
		c.nameToProject = make(map[string]*api.Project, len(projects))
	}

	for _, project := range projects {
		c.nameToProject[project.Name] = project
	}

	return nil
}
