// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.

package resource

import (
	"context"
	_ "encoding/json"
	"fmt"
	"github.com/stretchr/testify/assert"
	_ "gopkg.in/yaml.v3"
	"io"
	_ "log"
	"net/http"
	"net/http/httptest"
	_ "net/url"
	_ "os"
	_ "path/filepath"
	_ "strings"
	"testing"
	"regexp"
)

func TestNewHTTPResource(t *testing.T) {
	h := NewHTTP()
	assert.NotNil(t, h)
}

func TestHTTPDecode(t *testing.T) {
	h := NewHTTP()
	assert.NotNil(t, h)
	decl:=`
endpoint: "https://example.foo"
body: |-
  test body
`

	assert.Nil(t, h.LoadDecl(decl))
	assert.Equal(t, "test body", h.Body)
}

func TestHTTPRead(t *testing.T) {
	h := NewHTTP()
	assert.NotNil(t, h)

	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		assert.Equal(t, req.URL.String(), "/resource/user/foo")
		n,e := rw.Write([]byte(`
type: "user"
attributes:
  name: "foo"
  gecos: "foo user"
`))
		assert.Nil(t, e)
		assert.Greater(t, n, 0)
	}))
	defer server.Close()

	decl := fmt.Sprintf(`
endpoint: "%s/resource/user/foo"
`, server.URL)

	assert.Nil(t, h.LoadDecl(decl))
	_,e := h.Read(context.Background())
	assert.Nil(t, e)
	assert.Greater(t, len(h.Body), 0)
	assert.Nil(t, h.Validate())
}

func TestHTTPCreate(t *testing.T) {
	userdecl := `
type: "user"
attributes:
  name: "foo"
  gecos: "foo user"
`

	h := NewHTTP()
	assert.NotNil(t, h)
	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		defer req.Body.Close()
		assert.Equal(t, req.URL.String(), "/resource/user")
		body, err := io.ReadAll(req.Body)
		assert.Nil(t, err)
		assert.Equal(t, userdecl, string(body))
	}))
	defer server.Close()

	re := regexp.MustCompile(`(?m)^(.*)$`)
	decl := fmt.Sprintf(`
endpoint: "%s/resource/user"
headers:
- name: "content-type"
  value: "application/yaml"
body: |
%s
`, server.URL, re.ReplaceAllString(userdecl, "  $1"))
	assert.Nil(t, h.LoadDecl(decl))
	assert.Greater(t, len(h.Body), 0)
	e := h.Create()
	assert.Nil(t, e)
}
