// 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 config

import (
	"crypto/tls"
	"fmt"
	"net/http"
	"net/http/cookiejar"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"time"

	"github.com/gofrs/flock"
	homedir "github.com/mitchellh/go-homedir"
	ini "gopkg.in/ini.v1"
)

// Output formats
const (
	COLUMN = "column"
	CSV    = "csv"
	JSON   = "json"
	TABLE  = "table"
	TEXT   = "text"
	DEFAULT= "default"
)

// ServerProfile describes a management server
type ServerProfile struct {
	URL       string       `ini:"url"`
	Username  string       `ini:"username"`
	Password  string       `ini:"password"`
	Domain    string       `ini:"domain"`
	APIKey    string       `ini:"apikey"`
	SecretKey string       `ini:"secretkey"`
	Client    *http.Client `ini:"-"`
}

// Core block describes common options for the CLI
type Core struct {
	Prompt       string `ini:"prompt"`
	AsyncBlock   bool   `ini:"asyncblock"`
	Timeout      int    `ini:"timeout"`
	Output       string `ini:"output"`
	VerifyCert   bool   `ini:"verifycert"`
	ProfileName  string `ini:"profile"`
	AutoComplete bool   `ini:"autocomplete"`
}

// Config describes CLI config file and default options
type Config struct {
	Dir           string
	ConfigFile    string
	HistoryFile   string
	LogFile       string
	HasShell      bool
	Core          *Core
	ActiveProfile *ServerProfile
}

func GetOutputFormats() []string {
 return []string {"column", "csv", "json", "table", "text", "default"}
}

func CheckIfValuePresent(dataset []string, element string) bool {
	for _, arg := range dataset {
		if arg == element {
			return true
		}
	}
	return false
}
// CacheFile returns the path to the cache file for a server profile
func (c Config) CacheFile() string {
	cacheDir := path.Join(c.Dir, "profiles")
	cacheFileName := "cache"
	if c.Core != nil && len(c.Core.ProfileName) > 0 {
		cacheFileName = c.Core.ProfileName + ".cache"
	}
	checkAndCreateDir(cacheDir)
	return path.Join(cacheDir, cacheFileName)
}

func hasAccess(path string) bool {
	status := true
	file, err := os.Open(path)
	if (err != nil) {
		status = false
	}
	file.Close()
	return status
}

func checkAndCreateDir(path string) string {
	if fileInfo, err := os.Stat(path); os.IsNotExist(err) || !fileInfo.IsDir() {
		err := os.Mkdir(path, 0700)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}
	isAccsessible := hasAccess(path)
	if !isAccsessible {
		fmt.Println("User isn't authorized to access the config file")
		os.Exit(1)
	}
	return path
}

func getDefaultConfigDir() string {
	home, err := homedir.Dir()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	return checkAndCreateDir(path.Join(home, ".cmk"))
}

func defaultCoreConfig() Core {
	return Core{
		Prompt:      "🐱",
		AsyncBlock:  true,
		Timeout:     1800,
		Output:      JSON,
		VerifyCert:  true,
		ProfileName: "localcloud",
		AutoComplete: true,
	}
}

func defaultProfile() ServerProfile {
	return ServerProfile{
		URL:       "http://localhost:8080/client/api",
		Username:  "admin",
		Password:  "password",
		Domain:    "/",
		APIKey:    "",
		SecretKey: "",
	}
}

func defaultConfig() *Config {
	configDir := getDefaultConfigDir()
	defaultCoreConfig := defaultCoreConfig()
	defaultProfile := defaultProfile()
	return &Config{
		Dir:           configDir,
		ConfigFile:    path.Join(configDir, "config"),
		HistoryFile:   path.Join(configDir, "history"),
		LogFile:       path.Join(configDir, "log"),
		HasShell:      false,
		Core:          &defaultCoreConfig,
		ActiveProfile: &defaultProfile,
	}
}

var profiles []string

// GetProfiles returns list of available profiles
func GetProfiles() []string {
	return profiles
}

func newHTTPClient(cfg *Config) *http.Client {
	jar, _ := cookiejar.New(nil)
	client := &http.Client{
		Jar: jar,
		Transport: &http.Transport{
			Proxy:           http.ProxyFromEnvironment,
			TLSClientConfig: &tls.Config{InsecureSkipVerify: !cfg.Core.VerifyCert},
		},
	}
	client.Timeout = time.Duration(time.Duration(cfg.Core.Timeout) * time.Second)
	return client
}

func setActiveProfile(cfg *Config, profile *ServerProfile) {
	cfg.ActiveProfile = profile
	cfg.ActiveProfile.Client = newHTTPClient(cfg)
}

func reloadConfig(cfg *Config) *Config {
	fileLock := flock.New(path.Join(getDefaultConfigDir(), "lock"))
	err := fileLock.Lock()
	if err != nil {
		fmt.Println("Failed to grab config file lock, please try again")
		return cfg
	}
	cfg = saveConfig(cfg)
	fileLock.Unlock()
	LoadCache(cfg)
	return cfg
}

func readConfig(cfg *Config) *ini.File {
	conf, err := ini.LoadSources(ini.LoadOptions{
		IgnoreInlineComment: true,
	}, cfg.ConfigFile)

	if err != nil {
		fmt.Printf("Fail to read config file: %v", err)
		os.Exit(1)
	}
	return conf
}

func saveConfig(cfg *Config) *Config {
	if _, err := os.Stat(cfg.Dir); err != nil {
		os.Mkdir(cfg.Dir, 0700)
	}

	// Save on missing config
	if _, err := os.Stat(cfg.ConfigFile); err != nil {
		defaultCoreConfig := defaultCoreConfig()
		defaultProfile := defaultProfile()
		conf := ini.Empty()
		conf.Section(ini.DEFAULT_SECTION).ReflectFrom(&defaultCoreConfig)
		conf.Section(defaultCoreConfig.ProfileName).ReflectFrom(&defaultProfile)
		conf.SaveTo(cfg.ConfigFile)
	}

	conf := readConfig(cfg)

	core, err := conf.GetSection(ini.DEFAULT_SECTION)
	if core == nil || err != nil {
		defaultCore := defaultCoreConfig()
		section, _ := conf.NewSection(ini.DEFAULT_SECTION)
		section.ReflectFrom(&defaultCore)
		cfg.Core = &defaultCore
	} else {
		// Write
		if cfg.Core != nil {
			conf.Section(ini.DEFAULT_SECTION).ReflectFrom(&cfg.Core)
		}
		// Update
		core := new(Core)
		conf.Section(ini.DEFAULT_SECTION).MapTo(core)
		if (!conf.Section(ini.DEFAULT_SECTION).HasKey("autocomplete")) {
			core.AutoComplete = true
		}
		cfg.Core = core
	}

	profile, err := conf.GetSection(cfg.Core.ProfileName)
	if profile == nil {
		activeProfile := defaultProfile()
		section, _ := conf.NewSection(cfg.Core.ProfileName)
		section.ReflectFrom(&activeProfile)
		setActiveProfile(cfg, &activeProfile)
	} else {
		// Write
		if cfg.ActiveProfile != nil {
			conf.Section(cfg.Core.ProfileName).ReflectFrom(&cfg.ActiveProfile)
		}
		// Update
		profile := new(ServerProfile)
		conf.Section(cfg.Core.ProfileName).MapTo(profile)
		setActiveProfile(cfg, profile)
	}
	// Save
	conf.SaveTo(cfg.ConfigFile)

	// Update available profiles list
	profiles = []string{}
	for _, profile := range conf.Sections() {
		if profile.Name() == ini.DEFAULT_SECTION {
			continue
		}
		profiles = append(profiles, profile.Name())
	}

	return cfg
}

// LoadProfile loads an existing profile
func (c *Config) LoadProfile(name string) {
	Debug("Trying to load profile: " + name)
	conf := readConfig(c)
	section, err := conf.GetSection(name)
	if err != nil || section == nil {
		fmt.Printf("Unable to load profile '%s': %v", name, err)
		os.Exit(1)
	}
	profile := new(ServerProfile)
	conf.Section(name).MapTo(profile)
	setActiveProfile(c, profile)
	c.Core.ProfileName = name
}

// UpdateConfig updates and saves config
func (c *Config) UpdateConfig(key string, value string, update bool) {
	switch key {
	case "prompt":
		c.Core.Prompt = value
	case "asyncblock":
		c.Core.AsyncBlock = value == "true"
	case "display":
		fallthrough
	case "output":
		c.Core.Output = value
	case "timeout":
		intValue, err := strconv.Atoi(value)
		if err != nil {
			fmt.Println("Error caught while setting timeout:", err)
		}
		c.Core.Timeout = intValue
	case "profile":
		c.Core.ProfileName = value
		c.ActiveProfile = nil
	case "url":
		c.ActiveProfile.URL = value
	case "username":
		c.ActiveProfile.Username = value
	case "password":
		c.ActiveProfile.Password = value
	case "domain":
		c.ActiveProfile.Domain = value
	case "apikey":
		c.ActiveProfile.APIKey = value
	case "secretkey":
		c.ActiveProfile.SecretKey = value
	case "verifycert":
		c.Core.VerifyCert = value == "true"
	case "debug":
		if value == "true" || value == "on" {
			EnableDebugging()
		} else {
			DisableDebugging()
		}
	case "autocomplete":
		c.Core.AutoComplete = value == "true"
	default:
		fmt.Println("Invalid option provided:", key)
		return
	}

	Debug("UpdateConfig key:", key, " value:", value, " update:", update)

	if update {
		reloadConfig(c)
	}
}

// NewConfig creates or reload config and loads API cache
func NewConfig(configFilePath *string) *Config {
	defaultConf := defaultConfig()
	defaultConf.Core = nil
	defaultConf.ActiveProfile = nil
	if *configFilePath != "" {
		defaultConf.ConfigFile, _ = filepath.Abs(*configFilePath)
		if _, err := os.Stat(defaultConf.ConfigFile); os.IsNotExist(err) {
			fmt.Println("Config file doesn't exist.")
			os.Exit(1)
		}
	}
	cfg := reloadConfig(defaultConf)
	LoadCache(cfg)
	return cfg
}
