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

package resource

import (
	"context"
	"decl/tests/mocks"
	_ "encoding/json"
	_ "fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/network"
	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/stretchr/testify/assert"
	_ "io"
	_ "net/http"
	_ "net/http/httptest"
	_ "net/url"
	_ "os"
	_ "strings"
	"testing"
)

func TestNewContainerResource(t *testing.T) {
	c := NewContainer(&mocks.MockContainerClient{})
	assert.NotEqual(t, nil, c)
}

func TestReadContainer(t *testing.T) {
	ctx := context.Background()
	decl := `
  name: "testcontainer"
  image: "alpine"
  state: present
`
	m := &mocks.MockContainerClient{
		InjectContainerList: func(ctx context.Context, options container.ListOptions) ([]types.Container, error) {
			return []types.Container{
				{ID: "123456789abc"},
				{ID: "123456789def"},
			}, nil
		},
		InjectContainerInspect: func(ctx context.Context, containerID string) (types.ContainerJSON, error) {
			return types.ContainerJSON{
				ContainerJSONBase: &types.ContainerJSONBase{
					ID:    "123456789abc",
					Name:  "test",
					Image: "alpine",
				}}, nil
		},
	}

	c := NewContainer(m)
	assert.NotEqual(t, nil, c)

	e := c.LoadDecl(decl)
	assert.Equal(t, nil, e)
	assert.Equal(t, "testcontainer", c.Name)

	resourceYaml, readContainerErr := c.Read(ctx)
	assert.Equal(t, nil, readContainerErr)
	assert.Greater(t, len(resourceYaml), 0)
}

func TestCreateContainer(t *testing.T) {
	m := &mocks.MockContainerClient{
		InjectContainerCreate: func(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {
			return container.CreateResponse{ID: "abcdef012", Warnings: []string{}}, nil
		},
		InjectContainerRemove: func(context.Context, string, container.RemoveOptions) error {
			return nil
		},
	}

	decl := `
  name: "testcontainer"
  image: "alpine"
  state: present
`
	c := NewContainer(m)
	e := c.LoadDecl(decl)
	assert.Equal(t, nil, e)
	assert.Equal(t, "testcontainer", c.Name)

	applyErr := c.Apply()
	assert.Equal(t, nil, applyErr)

	c.State = "absent"

	applyDeleteErr := c.Apply()
	assert.Equal(t, nil, applyDeleteErr)
}
