/*
 * 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 file

import (
	"bytes"
	"errors"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"runtime"
	"strings"
)

import (
	gxset "github.com/dubbogo/gost/container/set"
	perrors "github.com/pkg/errors"
)

import (
	"github.com/apache/dubbo-go/common"
	"github.com/apache/dubbo-go/config_center"
	"github.com/apache/dubbo-go/config_center/parser"
)

var (
	osType = runtime.GOOS
)

const (
	windowsOS = "windows"
)

const (
	ParamNamePrefix               = "dubbo.config-center."
	ConfigCenterDirParamName      = ParamNamePrefix + "dir"
	ConfigCenterEncodingParamName = ParamNamePrefix + "encoding"
	defaultConfigCenterEncoding   = "UTF-8"
)

// FileSystemDynamicConfiguration
type FileSystemDynamicConfiguration struct {
	config_center.BaseDynamicConfiguration
	url           *common.URL
	rootPath      string
	encoding      string
	cacheListener *CacheListener
	parser        parser.ConfigurationParser
}

func newFileSystemDynamicConfiguration(url *common.URL) (*FileSystemDynamicConfiguration, error) {
	encode := url.GetParam(ConfigCenterEncodingParamName, defaultConfigCenterEncoding)

	root := url.GetParam(ConfigCenterDirParamName, "")
	var c *FileSystemDynamicConfiguration

	root, err := mkdirIfNecessary(root)
	if err != nil {
		return nil, err
	}

	c = &FileSystemDynamicConfiguration{
		url:      url,
		rootPath: root,
		encoding: encode,
	}

	c.cacheListener = NewCacheListener(c.rootPath)

	return c, nil
}

// RootPath get root path
func (fsdc *FileSystemDynamicConfiguration) RootPath() string {
	return fsdc.rootPath
}

// Parser Get Parser
func (fsdc *FileSystemDynamicConfiguration) Parser() parser.ConfigurationParser {
	return fsdc.parser
}

// SetParser Set Parser
func (fsdc *FileSystemDynamicConfiguration) SetParser(p parser.ConfigurationParser) {
	fsdc.parser = p
}

// AddListener Add listener
func (fsdc *FileSystemDynamicConfiguration) AddListener(key string, listener config_center.ConfigurationListener,
	opts ...config_center.Option) {
	tmpOpts := &config_center.Options{}
	for _, opt := range opts {
		opt(tmpOpts)
	}

	tmpPath := fsdc.GetPath(key, tmpOpts.Group)
	fsdc.cacheListener.AddListener(tmpPath, listener)
}

// RemoveListener Remove listener
func (fsdc *FileSystemDynamicConfiguration) RemoveListener(key string, listener config_center.ConfigurationListener,
	opts ...config_center.Option) {
	tmpOpts := &config_center.Options{}
	for _, opt := range opts {
		opt(tmpOpts)
	}

	tmpPath := fsdc.GetPath(key, tmpOpts.Group)
	fsdc.cacheListener.RemoveListener(tmpPath, listener)
}

// GetProperties get properties file
func (fsdc *FileSystemDynamicConfiguration) GetProperties(key string, opts ...config_center.Option) (string, error) {
	tmpOpts := &config_center.Options{}
	for _, opt := range opts {
		opt(tmpOpts)
	}

	tmpPath := fsdc.GetPath(key, tmpOpts.Group)
	file, err := ioutil.ReadFile(tmpPath)
	if err != nil {
		return "", perrors.WithStack(err)
	}
	return string(file), nil
}

// GetRule get Router rule properties file
func (fsdc *FileSystemDynamicConfiguration) GetRule(key string, opts ...config_center.Option) (string, error) {
	return fsdc.GetProperties(key, opts...)
}

// GetInternalProperty get value by key in Default properties file(dubbo.properties)
func (fsdc *FileSystemDynamicConfiguration) GetInternalProperty(key string, opts ...config_center.Option) (string,
	error) {
	return fsdc.GetProperties(key, opts...)
}

// PublishConfig will publish the config with the (key, group, value) pair
func (fsdc *FileSystemDynamicConfiguration) PublishConfig(key string, group string, value string) error {
	tmpPath := fsdc.GetPath(key, group)
	return fsdc.write2File(tmpPath, value)
}

// GetConfigKeysByGroup will return all keys with the group
func (fsdc *FileSystemDynamicConfiguration) GetConfigKeysByGroup(group string) (*gxset.HashSet, error) {
	tmpPath := fsdc.GetPath("", group)
	r := gxset.NewSet()

	fileInfo, _ := ioutil.ReadDir(tmpPath)

	for _, file := range fileInfo {
		// list file
		if file.IsDir() {
			continue
		}

		r.Add(file.Name())
	}

	return r, nil
}

// RemoveConfig will remove tconfig_center/nacos/impl_testhe config whit hte (key, group)
func (fsdc *FileSystemDynamicConfiguration) RemoveConfig(key string, group string) error {
	tmpPath := fsdc.GetPath(key, group)
	_, err := fsdc.deleteDelay(tmpPath)
	return err
}

// Close close file watcher
func (fsdc *FileSystemDynamicConfiguration) Close() error {
	return fsdc.cacheListener.Close()
}

// GetPath get path
func (fsdc *FileSystemDynamicConfiguration) GetPath(key string, group string) string {
	if len(key) == 0 {
		return filepath.Join(fsdc.rootPath, group)
	}

	if len(group) == 0 {
		group = config_center.DEFAULT_GROUP
	}

	return filepath.Join(fsdc.rootPath, group, adapterKey(key))
}

func (fsdc *FileSystemDynamicConfiguration) deleteDelay(path string) (bool, error) {
	if len(path) == 0 {
		return false, nil
	}

	if err := os.RemoveAll(path); err != nil {
		return false, err
	}

	return true, nil
}

func (fsdc *FileSystemDynamicConfiguration) write2File(fp string, value string) error {
	if err := forceMkdirParent(fp); err != nil {
		return perrors.WithStack(err)
	}

	return ioutil.WriteFile(fp, []byte(value), os.ModePerm)
}

func forceMkdirParent(fp string) error {
	return createDir(getParentDirectory(fp))
}

func createDir(path string) error {
	// create dir, chmod is drwxrwxrwx(0777)
	if err := os.MkdirAll(path, os.ModePerm); err != nil {
		return err
	}

	return nil
}

func getParentDirectory(fp string) string {
	return substr(fp, 0, strings.LastIndex(fp, string(filepath.Separator)))
}

func substr(s string, pos, length int) string {
	runes := []rune(s)
	l := pos + length
	if l > len(runes) {
		l = len(runes)
	}

	return string(runes[pos:l])
}

// Home returns the home directory for the executing user.
//
// This uses an OS-specific method for discovering the home directory.
// An error is returned if a home directory cannot be detected.
func Home() (string, error) {
	currentUser, err := user.Current()
	if nil == err {
		return currentUser.HomeDir, nil
	}

	// cross compile support
	if windowsOS == osType {
		return homeWindows()
	}

	// Unix-like system, so just assume Unix
	return homeUnix()
}

func homeUnix() (string, error) {
	// First prefer the HOME environmental variable
	if home := os.Getenv("HOME"); home != "" {
		return home, nil
	}

	// If that fails, try the shell
	var stdout bytes.Buffer
	cmd := exec.Command("sh", "-c", "eval echo ~$USER")
	cmd.Stdout = &stdout
	if err := cmd.Run(); err != nil {
		return "", err
	}

	result := strings.TrimSpace(stdout.String())
	if len(result) == 0 {
		return "", errors.New("blank output when reading home directory")
	}

	return result, nil
}

func homeWindows() (string, error) {
	drive := os.Getenv("HOMEDRIVE")
	homePath := os.Getenv("HOMEPATH")
	home := drive + homePath
	if len(drive) == 0 || len(homePath) == 0 {
		home = os.Getenv("USERPROFILE")
	}
	if len(home) == 0 {
		return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
	}

	return home, nil
}

func mkdirIfNecessary(urlRoot string) (string, error) {
	if !legalPath(urlRoot) {
		// not exist, use default, mac is: /XXX/xx/.dubbo/config-center
		rp, err := Home()
		if err != nil {
			return "", perrors.WithStack(err)
		}

		urlRoot = adapterUrl(rp)
	}

	if _, err := os.Stat(urlRoot); err != nil {
		// it must be dir, if not exist, will create
		if err = createDir(urlRoot); err != nil {
			return "", perrors.WithStack(err)
		}
	}

	return urlRoot, nil
}

func legalPath(path string) bool {
	if len(path) == 0 {
		return false
	}
	if _, err := os.Stat(path); err != nil {
		return false
	}

	return true
}

func adapterUrl(rp string) string {
	if osType == windowsOS {
		return filepath.Join(rp, "_dubbo", "config-center")
	}

	return filepath.Join(rp, ".dubbo", "config-center")
}

// used for GetPath. param key default is instance's id.
// e.g: (ip:port) 127.0.0.1:20081, in windows env, will change to 127_0_0_1_20081
func adapterKey(key string) string {
	if len(key) == 0 {
		return ""
	}

	if osType == windowsOS {
		return strings.ReplaceAll(strings.ReplaceAll(key, ".", "_"), ":", "_")
	}

	return key
}
