package config

import (
	"io/ioutil"
	"path/filepath"

	"github.com/filtr/infrastructure/go/openvpn-route-updater/internal/logger"
	"github.com/pkg/errors"
	yaml "gopkg.in/yaml.v2"
)

// MainConfig - config consists list of groups with settings, list of admin group names and admin groups themselves.
type MainConfig struct {
	AdminGroupNames   []string       `yaml:"adminGroups"`
	Groups            []*GroupConfig `yaml:"groups"`
	AdminGroupConfigs []*GroupConfig
	DefaultAwsProfile string `yaml:"defaultAwsProfile"`
}

// MainConfigManager - manager which operates with config data
type MainConfigManager struct {
	log           logger.Logger
	Config        MainConfig
	GroupManagers []*GroupConfigManager
}

// SetLogger - set logger -_-
func (c *MainConfigManager) SetLogger(log logger.Logger) {
	c.log = log
}

// ReadConfig - implementation for MainConfig
func ReadConfig(name string) (*MainConfig, error) {
	filename, err := filepath.Abs(name)
	if err != nil {
		return nil, errors.Wrap(err, "Config file path not found")
	}

	yamlFile, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, errors.Wrap(err, "Error reading config file")
	}

	// TODO Validate config
	config := &MainConfig{}
	err = yaml.Unmarshal(yamlFile, config)
	if err != nil {
		return nil, errors.Wrap(err, "Error unmarshalling config")
	}
	return config, nil
}

// InitializeManager - fill in default aws profile where needed and generate admin group configs,
func (c *MainConfigManager) InitializeManager() {
	// set default aws profile for zones if it was not specified
	for i := range c.Config.Groups {
		for j := range c.Config.Groups[i].Zones {
			if c.Config.Groups[i].Zones[j].AwsProfile == "" {
				c.Config.Groups[i].Zones[j].AwsProfile = c.Config.DefaultAwsProfile
			}
		}
	}
	// Generate Admin groups
	for _, adminGroup := range c.Config.AdminGroupNames {
		gm := &GroupConfigManager{log: c.log, Group: &GroupConfig{Name: adminGroup}}
		gm.Group.Name = adminGroup
		for _, group := range c.Config.Groups {
			gm.Append(group)
		}
		c.log.Debugf("%v", gm)
		c.Config.AdminGroupConfigs = append(c.Config.AdminGroupConfigs, gm.Group)
	}
}
