package operator

import (
	"github.com/juju/errors"
	"github.com/pingcap/schrodinger/config"
	"github.com/pingcap/schrodinger/manager/operator/apps"
	"github.com/pingcap/schrodinger/manager/operator/cluster/k8s"
	"github.com/pingcap/schrodinger/manager/operator/proc"
	"github.com/pingcap/schrodinger/manager/operator/task"
	"github.com/pingcap/schrodinger/util"
)

// Operator defines a set of kube operator
type Operator struct {
	*apps.AppController
	*proc.ProcsController
	*task.TasksController
	*k8s.ClusterController
}

// NewOperator returns an instance of Operator
func NewOperator(config *config.Config) (*Operator, error) {
	kubeCli, clusterCli, helmCli, err := util.CreateK8sClientAndClusterSet(
		config.KubeConfig.ConfigPath,
		config.KubeConfig.TillerPort)

	if err != nil {
		return nil, errors.Trace(err)
	}

	return &Operator{
		apps.NewAPPController(kubeCli),
		proc.NewProcsController(kubeCli),
		task.NewTasksController(),
		k8s.NewClusterController(
			kubeCli,
			clusterCli,
			helmCli,
			config.KubeConfig.Namespace,
			config.Cat.AgentPort,
			config.KubeConfig.ChartPath),
	}, nil
}
