// 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"
)

// 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"`
}

// 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"}
}

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 {
	isAccsessible := hasAccess(path)
	if !isAccsessible {
		fmt.Println("User isn't authorized to access the config file")
		os.Exit(1)
	}
	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)
		}
	}
	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",
	}
}

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)
		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()
		}
	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
}
