package rules

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	"iwarma.ru/console/correlator/config"
)

// ObtainAuthToken Get auth token from web interface
func ObtainAuthToken() (string, error) {
	body, err := json.Marshal(struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}{
		Username: viper.GetString(config.ConsoleUsername),
		Password: viper.GetString(config.ConsolePassword)})
	if err != nil {
		return "", err
	}

	request, err := http.NewRequest("POST", viper.GetString(config.ConsoleUrlToken), bytes.NewBuffer(body))
	if err != nil {
		log.Debugf("#0 Request to \"%v\"", viper.GetString(config.ConsoleUrlToken))
		return "", err
	}

	request.Header.Set("Content-Type", "application/json")

	var client *http.Client

	if viper.GetBool(config.ConsoleIgnoreSSLErrors) {
		transport := &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
		client = &http.Client{Transport: transport}
	} else {
		client = &http.Client{}
	}

	resp, err := client.Do(request)
	if err != nil {
		log.Debugf("# 1Request to \"%v\"", viper.GetString(config.ConsoleUrlToken))
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("got bad status code: %v", resp.StatusCode)
	}

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", nil
	}

	var data map[string]interface{}
	err = json.Unmarshal(respBody, &data)
	if err != nil {
		return "", err
	}

	if token, ok := data["token"].(string); ok {
		return token, nil
	} else {
		return "", fmt.Errorf("can't read response from %v", data)
	}
}
