package apps

import (
	"context"
	"strings"

	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/pingcap/schrodinger/manager/operator/apps/mysql"
	"github.com/pingcap/schrodinger/manager/operator/apps/prometheus"
	"github.com/pingcap/schrodinger/manager/operator/apps/tools"
	"github.com/pingcap/schrodinger/pkg/types"
	"github.com/pingcap/schrodinger/util"
	"k8s.io/client-go/kubernetes"
)

// AppController is defines a controller to manager apps
type AppController struct {
	k8sCli      kubernetes.Interface
	sqlClient   *mysql.SQLClient
	toolClient  *tools.ToolClient
	promeClient *prometheus.PromeClient
}

// NewAPPController creates apps controller
func NewAPPController(k8sCli kubernetes.Interface) *AppController {
	return &AppController{
		k8sCli:      k8sCli,
		sqlClient:   mysql.NewMysqlClient(k8sCli),
		toolClient:  tools.NewToolsClient(k8sCli),
		promeClient: prometheus.NewPromeClient(k8sCli),
	}
}

// CreateAPP creates app
func (c *AppController) CreateAPP(ctx context.Context, app *types.APPConfig) error {
	if app.IsTool() {
		return errors.Trace(c.toolClient.CreateAPP(ctx, app))
	}

	if app.IsProme() {
		return errors.Trace(c.promeClient.CreateAPP(ctx, app))
	}

	if app.IsMysql() || app.IsMariaDB() {
		return errors.Trace(c.sqlClient.CreateAPP(ctx, app))
	}

	return errors.NotSupportedf("app type %s", app.Type)
}

// DeleteAPP deletes app
func (c *AppController) DeleteAPP(ctx context.Context, namespace string, name string) error {
	exist, err := util.CheckNamespaceIsExist(namespace, c.k8sCli)
	if err != nil {
		return errors.Trace(err)
	}
	if !exist {
		log.Infof("namespace %s not exist, do not need to delete app", namespace)
		return nil
	}

	err = util.DeletePod(namespace, name, c.k8sCli)
	if err != nil && !strings.Contains(err.Error(), "not exist") {
		return errors.Trace(err)
	}

	return nil
}
