package parser

import (
	"esperframework/options"
	"os"
	"path/filepath"
	"testing"

	"github.com/matryer/is"
)

// Use fake options when necessary
var hd, _ = os.UserHomeDir()
var subdirs = "/Projects/packages/webframework"
var opts = &options.Options{
	Root:            filepath.Join(hd, subdirs, "/tests/astree"),
	Ext:             ".html",
	AppDir:          "src/app",
	AppPath:         filepath.Join(hd, subdirs, "/tests/astree/src/app"),
	OutDir:          "build",
	OutPath:         filepath.Join(hd, subdirs, "/tests/astree/build"),
	PublicPath:      "public",
	CachePath:       filepath.Join(hd, subdirs, "/tests/astree/build/cache"),
	CacheClientPath: filepath.Join(hd, subdirs, "/tests/astree/build/client"),
	DepGraphPath:    filepath.Join(hd, subdirs, "/tests/astree/build/cache/dep_graph.json"),
	Dev:             true,
	ModuleDev:       true,
}

// func TestParseTemplateBlocks(t *testing.T) {
// 	test := struct {
// 		output TemplateData
// 	}{
// 		output: TemplateData{
// 			Markup: OutputMarkupTree{
// 				HTML: MarkupItem{
// 					Typ: "Fragment",
// 					Children: []MarkupItem{
// 						{
// 							Typ:         "Text",
// 							Data:        "\n\n\n\n\n\n\n\n",
// 							Start:       0,
// 							End:         8,
// 							Line:        1,
// 							SelfClosing: true,
// 						},
// 						{
// 							Typ:         "Element",
// 							Name:        "h1",
// 							Start:       8,
// 							End:         59,
// 							Line:        9,
// 							SelfClosing: false,
// 							Attributes: []MarkupItem{
// 								{
// 									Typ:         "Attribute",
// 									Name:        "class",
// 									Start:       12,
// 									End:         27,
// 									Line:        9,
// 									SelfClosing: false,
// 									Value: []MarkupItem{
// 										{
// 											Typ:         "Text",
// 											Data:        "heading",
// 											Start:       19,
// 											End:         26,
// 											Line:        9,
// 											SelfClosing: false,
// 										},
// 									},
// 								},
// 							},
// 							Children: []MarkupItem{
// 								{
// 									Typ:         "Text",
// 									Data:        "\n\t",
// 									Start:       28,
// 									End:         30,
// 									Line:        9,
// 									SelfClosing: true,
// 								},
// 								{
// 									Typ:   "Element",
// 									Name:  "span",
// 									Start: 30,
// 									End:   53,
// 									Line:  10,
// 									Children: []MarkupItem{
// 										{
// 											Typ:         "Text",
// 											Data:        "\n\t\tHello\n\t",
// 											Start:       36,
// 											End:         46,
// 											Line:        10,
// 											SelfClosing: true,
// 										},
// 									},
// 								},
// 								{
// 									Typ:         "Text",
// 									Data:        "\n",
// 									Start:       53,
// 									End:         54,
// 									Line:        12,
// 									SelfClosing: true,
// 								},
// 							},
// 						},
// 					},
// 				},
// 			},
// 			Styles: TemplateBlockData{
// 				Attrs: map[string]string{
// 					"lang": "pcss",
// 				},
// 				Data: "\n\n\n\n\n\n\n\n\n\n\n\n\n\nh1 {\n\t\tcolor: red;\n\t}\n",
// 			},
// 			Script: TemplateBlockData{
// 				Attrs: map[string]string{
// 					"lang": "ts",
// 				},
// 				Data: "console.log(\"Hello\")\n",
// 			},
// 			Head: []HeadBlockItem{
// 				{
// 					Kind: Kind{
// 						Name:    "link",
// 						RelType: "rel",
// 						Value:   "stylesheet",
// 					},
// 					Attrs: map[string]string{
// 						"preload": "true",
// 					},
// 					Path: Path{
// 						PathType: "href",
// 						RelPath:  "../styles/main.css",
// 					},
// 				},
// 			},
// 			MetaData: TemplateMetaData{
// 				TemplateKind: "page",
// 				Path:         "/src/app/index.html",
// 				MetaDataPath: "/app/index.json",
// 			},
// 		},
// 	}

// 	// wd, _ := os.Getwd()
// 	// astreeTestPath := filepath.Join(wd, "../../../../../", "test", "astree")

// 	// cmd := exec.Command("bash", "-c", "cd "+astreeTestPath+" && "+"npm run dev")
// 	// stdout, err := cmd.Output()

// 	// if err != nil {
// 	// 	fmt.Println(err.Error())
// 	// 	return
// 	// }

// 	// // Print the output
// 	// fmt.Println(string(stdout))

// 	am := &options.ActionMeta{
// 		Action:     "STARTING_BUILD",
// 		Message:    "Starting build...",
// 		ActionPath: ".",
// 		Ext:        "any",
// 	}

// 	is := is.New(t)

// 	Parse(opts, am)

// 	file, _ := os.ReadFile(filepath.Join(opts.CachePath, "index.json"))

// 	var td TemplateData
// 	json.Unmarshal(file, &td)

// 	// out, _ := json.Marshal(test.output)

// 	// for i := 0; i < len(string(out)); i++ {
// 	// 	is.True(string(out)[i] == string(file)[i])
// 	// }

// 	// cl, _ := diff.Diff(string(out), string(file))
// 	// cl, _ := diff.Diff(test.output, cbs)
// 	// fmt.Printf("%+v\n", cl)

// 	// fmt.Printf("\n\nASSERT: %+v\n\nRESULT: %+v\n\n\n\n\n", test.output, cbs)

// 	//  fmt.Printf("%+v\n", reflect.DeepEqual(test.output, cbs))
// 	// fmt.Printf("%+v\n", reflect.DeepEqual(string(out), string(file)))
// 	is.Equal(test.output, td)
// }

func TestLexHeadBlock(t *testing.T) {
	tests := []struct {
		input  []byte
		output []HeadBlockItem
	}{
		{
			input:  []byte("<append:head></append:head>"),
			output: nil,
		},
		{
			input:  []byte("<append:head><!-- comment one -->\n<!-- comment two --></append:head>"),
			output: nil,
		},
		{
			input: []byte("<append:head><title>Page title</title></append:head>"),
			output: []HeadBlockItem{
				{
					Kind: Kind{
						Name: "title",
					},
					Value: "Page title",
				},
			},
		},
		{
			input: []byte("<append:head><meta name=\"description\" content=\"Page for testing\"></append:head>"),
			output: []HeadBlockItem{
				{
					Kind: Kind{
						Name: "meta",
					},
					Attrs: map[string]string{
						"name":    "description",
						"content": "Page for testing",
					},
				},
			},
		},
	}

	is := is.New(t)

	for _, test := range tests {
		l := &TBLexer{
			input:   test.input,
			state:   extractMarkup,
			options: opts,
		}

		td := New(l, newArgs{
			name:     "parser_test",
			isAppDir: true,
			fileKind: ".html",
		})

		// cl, _ := diff.Diff(test.output, (*l).component.headBlock)
		// fmt.Printf("%+v\n", cl)

		// fmt.Printf("\n\nEXP: %+v\n\nRES: %+v\n\n\n\n\n", test.output, td.Head)
		is.Equal(test.output, td.Head)
	}
}
