// 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"
_ "syscall"
	"testing"
_ "time"
)

func TestNewIptableResource(t *testing.T) {
	i := NewIptable()
	assert.NotNil(t, i)
}

func TestIptableApplyResourceTransformation(t *testing.T) {
	i := NewIptable()
	assert.NotNil(t, i)

	//e := f.Apply()
	//assert.Equal(t, nil, e)
}

func TestReadIptable(t *testing.T) {
	ctx := context.Background()
	testRule := NewIptable()
	assert.NotNil(t, testRule)

	declarationAttributes := `
  id: 0
  table: "filter"
  chain: "INPUT"
  source: "192.168.0.0/24"
  destination: "192.168.0.1"
  jump: "ACCEPT"
  state: present
`
	m := &MockCommand{
		Executor: func(value any) ([]byte, error) {
			return nil, nil
		},
		Extractor: func(output []byte, target any) error {
			testRule.Table = "filter"
			testRule.Chain = "INPUT"
			testRule.Id = 0
			testRule.In = "eth0"
			testRule.Source = "192.168.0.0/24"
			testRule.State = "present"
			return nil
		},
	}

	e := testRule.LoadDecl(declarationAttributes)
	assert.Nil(t, e)
  testRule.ReadCommand = (*Command)(m)
//	testRuleErr := testRule.Apply()
//	assert.Nil(t, testRuleErr)
	r, e := testRule.Read(ctx)

	assert.Nil(t, e)
	assert.NotNil(t, r)
	assert.Equal(t, "eth0", testRule.In)
}

func TestCreateIptable(t *testing.T) {
	testRule := NewIptable()
	assert.NotNil(t, testRule)

	
}

func TestIptableSetFlagValue(t *testing.T) {
	i := NewIptable()
	assert.NotNil(t, i)
	i.SetFlagValue("-i", "eth0")
	assert.Equal(t, "eth0", i.In)
}


func TestIptableChainExtractor(t *testing.T) {
	ipt := NewIptable()
	assert.NotNil(t, ipt)
	ipt.Chain = IptableChain("FOO")
	assert.Nil(t, ChainExtractor([]byte("-N FOO\n"), ipt))
	assert.Equal(t, IptableChain("FOO"), ipt.Chain)
}

func TestIptableRuleExtractorById(t *testing.T) {
	ipt := NewIptable()
	assert.NotNil(t, ipt)
	ipt.Table = IptableName("filter")
	ipt.Chain = IptableChain("FOO")
	ipt.Id = 1

	data := []byte(`
-N FOO
-A FOO -s 192.168.0.1/32 -j ACCEPT
`)
	assert.Nil(t, RuleExtractor(data, ipt))
	assert.Equal(t, IptableChain("FOO"), ipt.Chain)
	assert.Equal(t, IptableCIDR("192.168.0.1/32"), ipt.Source)
}

func TestIptableRuleExtractorByFlags(t *testing.T) {
	ipt := NewIptable()
	assert.NotNil(t, ipt)
	ipt.Table = IptableName("filter")
	ipt.Chain = IptableChain("FOO")
	ipt.Source = IptableCIDR("192.168.0.1/32")
	ipt.Jump = "ACCEPT"
	data := []byte(`
-N FOO
-A FOO -d 192.168.0.3/32 -j ACCEPT
-A FOO -s 192.168.0.3/32 -j ACCEPT
-A FOO -s 192.168.0.1/32 -j ACCEPT
`)
	assert.Nil(t, RuleExtractorMatchFlags(data, ipt))
	assert.Equal(t, uint(3), ipt.Id, ipt.Chain)
	assert.Equal(t, IptableChain("FOO"), ipt.Chain)
	assert.Equal(t, IptableCIDR("192.168.0.1/32"), ipt.Source)
}
