/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"strings"

	"github.com/apache/camel-k/pkg/util"
	p "github.com/gertd/go-pluralize"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	yaml "gopkg.in/yaml.v2"
)

const (
	// DefaultConfigName is the default config name
	DefaultConfigName = "kamel-config"

	// DefaultConfigLocation is the main place where the kamel content is stored
	DefaultConfigLocation = DefaultConfigName + ".yaml"

	// KamelTagName ---
	KamelTagName = "kamel"

	// MapstructureTagName ---
	MapstructureTagName = "mapstructure"
)

// Config is a helper class to manipulate kamel configuration files
type Config struct {
	location string
	content  map[string]interface{}
}

// LoadConfiguration loads a kamel configuration file
func LoadConfiguration() (*Config, error) {
	config := Config{
		location: viper.ConfigFileUsed(),
		content:  make(map[string]interface{}),
	}

	if config.location == "" {
		config.location = DefaultConfigLocation
	}

	if _, err := os.Stat(config.location); os.IsNotExist(err) {
		return &config, nil
	}

	data, err := ioutil.ReadFile(config.location)
	if err != nil {
		return &config, err
	}

	err = yaml.Unmarshal(data, &config.content)
	if err != nil {
		return nil, err
	}

	return &config, nil
}

// Update ---
func (cfg *Config) Update(cmd *cobra.Command, nodeID string, data interface{}, changedOnly bool) {
	values := make(map[string]interface{})

	pl := p.NewClient()
	val := reflect.ValueOf(data).Elem()

	for i := 0; i < val.NumField(); i++ {
		field := val.Type().Field(i)
		if !field.Anonymous {
			if ktag, ok := field.Tag.Lookup(KamelTagName); ok {
				ktags := strings.Split(ktag, ",")
				if util.StringSliceExists(ktags, "omitsave") {
					continue
				}
			}

			tag, ok := field.Tag.Lookup(MapstructureTagName)
			if !ok {
				continue
			}

			flagName := pl.Singular(tag)
			if flag := cmd.Flag(flagName); flag != nil && (flag.Changed || !changedOnly) {
				if !val.Field(i).IsZero() {
					values[tag] = val.Field(i).Interface()
				}
			}
		}
	}

	if len(values) > 0 {
		cfg.SetNode(nodeID, values)
	}
}

// SetNode allows to replace a subtree with a given content
func (cfg *Config) SetNode(nodeID string, nodeValues map[string]interface{}) {
	cfg.Delete(nodeID)
	node := cfg.navigate(cfg.content, nodeID, true)

	for k, v := range nodeValues {
		node[k] = v
	}
}

// Delete allows to remove a sub tree from the kamel content
func (cfg *Config) Delete(path string) {
	leaf := cfg.navigate(cfg.content, path, false)
	for k := range leaf {
		delete(leaf, k)
	}
}

// Save ---
func (cfg *Config) Save() error {
	root := filepath.Dir(cfg.location)
	if _, err := os.Stat(root); os.IsNotExist(err) {
		if e := os.MkdirAll(root, 0700); e != nil {
			return e
		}
	}

	data, err := yaml.Marshal(cfg.content)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(cfg.location, data, 0644)
}

func (cfg *Config) navigate(values map[string]interface{}, prefix string, create bool) map[string]interface{} {
	nodes := strings.Split(prefix, ".")

	for _, node := range nodes {
		v := values[node]

		if v == nil {
			if create {
				v = make(map[string]interface{})
				values[node] = v
			} else {
				return nil
			}
		}

		if m, ok := v.(map[string]interface{}); ok {
			values = m
		} else if mg, ok := v.(map[interface{}]interface{}); ok {
			converted := cfg.convert(mg)
			values[node] = converted
			values = converted
		} else {
			if create {
				child := make(map[string]interface{})
				values[node] = child
				return child
			}
			return nil
		}
	}
	return values
}

func (cfg *Config) convert(m map[interface{}]interface{}) map[string]interface{} {
	res := make(map[string]interface{})
	for k, v := range m {
		if ks, ok := k.(string); ok {
			res[ks] = v
		}
	}
	return res
}
