package odoo

import (
	"errors"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	S "bitbucket.org/robert2206/automation/modules/settings"
	"github.com/flosch/pongo2"
)

var (
	matchFirstCap  = regexp.MustCompile("(.)([A-Z][a-z]+)")
	matchAllCap    = regexp.MustCompile("([a-z0-9])([A-Z])")
	matchAllSpaces = regexp.MustCompile("(\\s*)")
)

// Create odoo instance
func Create(odooName string) error {
	// 1. snakeize name
	odooName = snakeizeName(odooName)
	log.Printf("snakeize odoo name: %v", odooName)

	// 2. build odoo path
	path := filepath.Join(S.Ctx.OdooRootPath, odooName)
	log.Printf("odoo path builded: %v", path)

	// 3. check if odoo path exists
	pathExists := existsPath(path)

	if pathExists {
		log.Printf("odoo path existence: %v", pathExists)
		return errors.New("odoo path exists")
	}

	log.Printf("odoo path existence: %v", pathExists)

	// 4. make odoo path
	err := makePath(odooName)

	if err != nil {
		return err
	}

	// 5. make odoo default paths
	err = makeDefaultPaths(odooName)

	if err != nil {
		log.Fatalf("odoo default paths cannot be created: %v", err.Error())
		return err
	}

	log.Printf("odoo default paths is created")

	// 6. make openerp-server.conf
	err = makeConfiguration(odooName)

	if err != nil {
		log.Fatalf("odoo configuration cannot be created: %v", err.Error())
		return err
	}

	log.Printf("odoo configuration is created")

	return nil
}

func snakeizeName(name string) string {
	snakeCase := matchFirstCap.ReplaceAllString(name, "${1}_${2}")
	snakeCase = matchAllCap.ReplaceAllString(snakeCase, "${1}_${2}")
	snakeCase = matchAllSpaces.ReplaceAllString(snakeCase, "")

	return strings.ToLower(snakeCase)
}

func existsPath(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

func makePath(odooName string) error {
	path := filepath.Join(S.Ctx.OdooRootPath, odooName)
	return os.Mkdir(path, 0777)
}

func makeDefaultPaths(odooName string) error {
	paths := [3]string{"custom-addons", "config", "files"}

	for i := 0; i < len(paths); i++ {
		path := filepath.Join(S.Ctx.OdooRootPath, odooName, paths[i])

		err := os.Mkdir(path, 0777)

		if err != nil {
			return err
		}
	}

	return nil
}

func makeConfiguration(odooName string) error {
	tmpl, err := pongo2.FromFile("data/templates/openerp-server.tpl")

	if err != nil {
		return err
	}

	tmpl = pongo2.Must(tmpl, err)

	out, _ := tmpl.Execute(pongo2.Context{
		"admin_password": "admin",
		"db_host":        "127.0.0.1",
		"db_port":        "8069",
		"db_name":        "odoo",
		"db_user":        "odoo",
	})

	confPath := filepath.Join(S.Ctx.OdooRootPath, odooName, "config", "openerp-server.conf")

	return ioutil.WriteFile(confPath, []byte(out), 0777)
}
