package helper

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"strings"

	"gitbase.de/apairon/mark2web/config"
	"github.com/flosch/pongo2"
)

// RequestFn will make a web request and returns map[string]interface form pongo2
func RequestFn(url *pongo2.Value, args ...*pongo2.Value) *pongo2.Value {
	u := url.String()
	Log.Noticef("requesting url via GET %s", u)

	resp, err := http.Get(u)
	if err != nil {
		Log.Panicf("could not get url '%s': %s", u, err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		Log.Panicf("could not read body from url '%s': %s", u, err)
	}

	Log.Debugf("output from url '%s':\n%s", u, string(body))

	if resp.StatusCode >= 400 {
		Log.Panicf("bad status '%d - %s' from url '%s'", resp.StatusCode, resp.Status, u)
	}

	contentType := resp.Header.Get("Content-Type")

	if strings.Contains(contentType, "json") {

	} else {
		Log.Panicf("is not json '%s' from url '%s'", contentType, u)
	}

	jsonMap := make(map[string]interface{})
	err = json.Unmarshal(body, &jsonMap)
	if err != nil {
		Log.Panicf("could not read json from '%s': %s", u, err)
	}

	return pongo2.AsValue(jsonMap)
}

// RenderFn renders a pongo2 template with additional context
func RenderFn(templateFilename, outDir, ctx *pongo2.Value, param ...*pongo2.Value) *pongo2.Value {
	ctxMapKey := ""
	body := ""

	for i, p := range param {
		switch i {
		case 0:
			ctxMapKey = p.String()
		case 1:
			body = p.String()
		}
	}

	newNodeConfig := new(config.PathConfigTree)
	fillNodeConfig(
		newNodeConfig,
		currentTreeNodeConfig.InputPath,
		currentTreeNodeConfig.OutputPath,
		outDir.String(),
		currentPathConfig,
	)
	if newNodeConfig.Config.Data == nil {
		newNodeConfig.Config.Data = make(map[string]interface{})
	}
	if ctxMapKey != "" {
		// as submap in Data
		newNodeConfig.Config.Data[ctxMapKey] = ctx.Interface()
	} else if m, ok := ctx.Interface().(map[string]interface{}); ok {
		// direct set data
		newNodeConfig.Config.Data = m
	}
	tplFilename := templateFilename.String()

	// fake via normal file behavior
	newNodeConfig.Config.Template = &tplFilename
	newNodeConfig.InputFiles = []string{""} // empty file is special for use InputString
	indexInFile := ""
	indexOutFile := "index.html"
	if idx := newNodeConfig.Config.Index; idx != nil {
		if idx.OutputFile != nil && *idx.OutputFile != "" {
			indexOutFile = *idx.OutputFile
		}
	}
	newNodeConfig.Config.Index = &config.IndexConfig{
		InputFile:   &indexInFile,
		OutputFile:  &indexOutFile,
		InputString: &body,
	}
	newNodeConfig.Hidden = true

	currentTreeNodeConfig.Sub = append(currentTreeNodeConfig.Sub, newNodeConfig)

	return pongo2.AsValue(nil)
}
