<commit_before>// Copyright 2015 Cutehacks AS. All rights reserved.
// License can be found in the LICENSE file.

package commands

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/howeyc/gopass"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"qpm.io/common"
	"qpm.io/qpm/core"
	"strconv"
	"strings"
	"text/template"
	"time"
)

func Prompt(prompt string, def string) chan string {
	replyChannel := make(chan string, 1)

	if def == "" {
		fmt.Printf(prompt + " ")
	} else {
		fmt.Printf(prompt+" [%s] ", def)
	}

	in := bufio.NewReader(os.Stdin)
	answer, _ := in.ReadString('\n')

	answer = strings.TrimSpace(answer)

	if len(answer) > 0 {
		replyChannel <- answer
	} else {
		replyChannel <- def
	}

	return replyChannel
}

func PromptPassword(prompt string) chan string {
	replyChannel := make(chan string, 1)
	fmt.Printf(prompt + " ")
	replyChannel <- string(gopass.GetPasswd())
	return replyChannel
}

type InitCommand struct {
	BaseCommand
	Pkg *common.PackageWrapper
}

func NewInitCommand(ctx core.Context) *InitCommand {
	return &InitCommand{
		BaseCommand: BaseCommand{
			Ctx: ctx,
		},
	}
}

func (ic InitCommand) Description() string {
	return "Initializes a new module in the current directory"
}

func (ic *InitCommand) RegisterFlags(flag *flag.FlagSet) {

}

func (ic *InitCommand) Run() error {

	ic.Pkg = &common.PackageWrapper{Package: common.NewPackage()}

	// TODO: Check ~/.gitconfig for name/email
	ic.Pkg.Author.Name = <-Prompt("Your name:", ic.Pkg.Author.Name)
	ic.Pkg.Author.Email = <-Prompt("Your email:", ic.Pkg.Author.Email)

	cwd, err := os.Getwd()
	if err != nil {
		ic.Error(err)
		cwd = ""
	} else {
		cwd = filepath.Base(cwd)
	}
	ic.Pkg.Name = <-Prompt("Unique package name:", cwd)
	ic.Pkg.Version.Label = <-Prompt("Initial version:", ic.Pkg.Version.Label)

	ic.Pkg.Repository.Url = <-Prompt("Repository:", "")

	if err := ic.Pkg.Save(); err != nil {
		return err
	}

	bootstrap := <-Prompt("Generate boilerplate:", "Y/n")
	if len(bootstrap) == 0 || strings.ToLower(string(bootstrap[0])) == "y" {
		ic.GenerateBoilerplate()
		ic.license("mit") // FIXME: add support for more licenses
	}
	return nil
}

var (
	funcMap = template.FuncMap{
		"dotSlash": func(dots string) string {
			return strings.Replace(dots, ".", "/", -1)
		},
	}
	modulePri = template.Must(template.New("modulePri").Funcs(funcMap).Parse(`
RESOURCES += \
    $$PWD/{{.PackageName}}.qrc
`))
	moduleQrc = template.Must(template.New("moduleQrc").Funcs(funcMap).Parse(`
<RCC>
    <qresource prefix="{{dotSlash .Namespace}}/{{.Name}}">
        <file>qmldir</file>
    </qresource>
</RCC>
`))
	qmldir = template.Must(template.New("qmldir").Funcs(funcMap).Parse(`
module {{.Namespace}}.{{.Name}}
`))
)

func (ic InitCommand) WriteBoilerPlate(filename string, tpl *template.Template, data interface{}) error {
	file, err := os.Create(filename)
	if err != nil {
		ic.Error(err)
		return err
	}
	defer file.Close()

	err = tpl.Execute(file, data)
	if err != nil {
		ic.Error(err)
		return err
	}

	return nil
}

func (ic InitCommand) GenerateBoilerplate() {
	module := struct {
		PackageName string
		Namespace   string
		Name        string
	}{
		PackageName: ic.Pkg.Name,
		Namespace:   strings.ToLower(<-Prompt("Namespace:", "com.example")),
		Name:        strings.ToLower(<-Prompt("Module name:", ic.Pkg.Name)),
	}

	ic.WriteBoilerPlate(ic.Pkg.Name+".pri", modulePri, module)
	ic.WriteBoilerPlate(ic.Pkg.Name+".qrc", moduleQrc, module)
	ic.WriteBoilerPlate("qmldir", qmldir, module)
}

type License struct {
	Key       string
	Name      string
	Permitted []string
	Forbidden []string
	Body      string
}

func (ic *InitCommand) license(license string) error {

	url := "https://api.github.com/licenses/" + license
	client := &http.Client{}

	request, err := http.NewRequest("GET", url, nil)<commit_msg>Make 'init' compatible with the new namespace packages.<commit_after>// Copyright 2015 Cutehacks AS. All rights reserved.
// License can be found in the LICENSE file.

package commands

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/howeyc/gopass"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"qpm.io/common"
	"qpm.io/qpm/core"
	"strconv"
	"strings"
	"text/template"
	"time"
)

func Prompt(prompt string, def string) chan string {
	replyChannel := make(chan string, 1)

	if def == "" {
		fmt.Printf(prompt + " ")
	} else {
		fmt.Printf(prompt+" [%s] ", def)
	}

	in := bufio.NewReader(os.Stdin)
	answer, _ := in.ReadString('\n')

	answer = strings.TrimSpace(answer)

	if len(answer) > 0 {
		replyChannel <- answer
	} else {
		replyChannel <- def
	}

	return replyChannel
}

func PromptPassword(prompt string) chan string {
	replyChannel := make(chan string, 1)
	fmt.Printf(prompt + " ")
	replyChannel <- string(gopass.GetPasswd())
	return replyChannel
}

func extractReverseDomain(email string) string {
	emailParts := strings.Split(email, "@")
	if len(emailParts) != 2 {
		return ""
	}
	domainParts := strings.Split(emailParts[1], ".")
	for i, j := 0, len(domainParts)-1; i < j; i, j = i+1, j-1 {
		domainParts[i], domainParts[j] = domainParts[j], domainParts[i]
	}
	return strings.Join(domainParts, ".")
}

func dotSlash(dots string) string {
	return strings.Replace(dots, ".", "/", -1)
}

func dotUnderscore(dots string) string {
	return strings.Replace(dots, ".", "_", -1)
}

type InitCommand struct {
	BaseCommand
	Pkg *common.PackageWrapper
}

func NewInitCommand(ctx core.Context) *InitCommand {
	return &InitCommand{
		BaseCommand: BaseCommand{
			Ctx: ctx,
		},
	}
}

func (ic InitCommand) Description() string {
	return "Initializes a new module in the current directory"
}

func (ic *InitCommand) RegisterFlags(flag *flag.FlagSet) {

}

func (ic *InitCommand) Run() error {

	ic.Pkg = &common.PackageWrapper{Package: common.NewPackage()}

	// TODO: Check ~/.gitconfig for name/email
	ic.Pkg.Author.Name = <-Prompt("Your name:", ic.Pkg.Author.Name)
	ic.Pkg.Author.Email = <-Prompt("Your email:", ic.Pkg.Author.Email)

	cwd, err := os.Getwd()
	if err != nil {
		ic.Error(err)
		cwd = ""
	} else {
		cwd = filepath.Base(cwd)
	}

	suggestedName := extractReverseDomain(ic.Pkg.Author.Email) + "." + cwd

	ic.Pkg.Name = <-Prompt("Unique package name:", suggestedName)
	ic.Pkg.Version.Label = <-Prompt("Initial version:", ic.Pkg.Version.Label)

	ic.Pkg.Repository.Url = <-Prompt("Repository:", "")

	if err := ic.Pkg.Save(); err != nil {
		return err
	}

	bootstrap := <-Prompt("Generate boilerplate:", "Y/n")
	if len(bootstrap) == 0 || strings.ToLower(string(bootstrap[0])) == "y" {
		ic.GenerateBoilerplate()
		ic.license("mit") // FIXME: add support for more licenses
	}
	return nil
}

var (
	funcMap = template.FuncMap{
		"dotSlash": dotSlash,
	}
	modulePri = template.Must(template.New("modulePri").Funcs(funcMap).Parse(`
RESOURCES += \
    $$PWD/{{.QrcFile}}
`))
	moduleQrc = template.Must(template.New("moduleQrc").Funcs(funcMap).Parse(`
<RCC>
    <qresource prefix="{{dotSlash .Package.Name}}">
        <file>qmldir</file>
    </qresource>
</RCC>
`))
	qmldir = template.Must(template.New("qmldir").Funcs(funcMap).Parse(`
module {{.Package.Name}}
`))
)

func (ic InitCommand) WriteBoilerPlate(filename string, tpl *template.Template, data interface{}) error {
	file, err := os.Create(filename)
	if err != nil {
		ic.Error(err)
		return err
	}
	defer file.Close()

	err = tpl.Execute(file, data)
	if err != nil {
		ic.Error(err)
		return err
	}

	return nil
}

func (ic InitCommand) GenerateBoilerplate() {

	fileBase := dotUnderscore(ic.Pkg.Name)

	module := struct {
		Package *common.PackageWrapper
		PriFile string
		QrcFile string
	}{
		Package: ic.Pkg,
		PriFile: fileBase+".pri",
		QrcFile: fileBase+".qrc",
	}

	ic.WriteBoilerPlate(module.PriFile, modulePri, module)
	ic.WriteBoilerPlate(module.QrcFile, moduleQrc, module)
	ic.WriteBoilerPlate("qmldir", qmldir, module)
}

type License struct {
	Key       string
	Name      string
	Permitted []string
	Forbidden []string
	Body      string
}

func (ic *InitCommand) license(license string) error {

	url := "https://api.github.com/licenses/" + license
	client := &http.Client{}

	request, err := http.NewRequest("GET", url, nil)
{'fraction_non_alphanumeric': 0.16379522520305193, 'fraction_numerical': 0.0033226679793256215, 'mean_word_length': 3.96760391198044, 'pattern_counts': {'":': 2, '<': 36, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2863641', 'n_tokens_mistral': 3136, 'n_tokens_neox': 2978, 'n_words': 654}