// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package core

import (
	"fmt"
	"strconv"
	"strings"
	"testing"
)

type xrefDef struct {
	xref, href string
}

type recognizeLinksTestCase struct {
	input    string
	xrefUses []string
	hrefUses []string
	xrefDefs []xrefDef
	tocs     []string
}

type recognizerAcc struct {
	DefaultLintRuleOverEvents

	xrefUses []string
	hrefUses []string
	xrefDefs []xrefDef
	tocs     []string
}

var _ LintRuleOverEvents = (*recognizerAcc)(nil)

func (r *recognizerAcc) OnLinkByXref(xref Token) {
	r.xrefUses = append(r.xrefUses, xref.Content)
}

func (r *recognizerAcc) OnLinkByURL(href Token) {
	r.hrefUses = append(r.hrefUses, href.Content)
}

func (r *recognizerAcc) OnXrefDefinition(xref, href Token) {
	r.xrefDefs = append(r.xrefDefs, xrefDef{xref.Content, href.Content})
}

func (r *recognizerAcc) OnTableOfContents(toc Token) {
	r.tocs = append(r.tocs, toc.Content)
}

func TestRecognizeLinks(t *testing.T) {
	cases := []recognizeLinksTestCase{
		{
			input: "before [link-and-xref] after [another-link-and-xref].",
			xrefUses: []string{
				"[link-and-xref]",
				"[another-link-and-xref]",
			},
		},
		{
			input: "something [link-and-xref]\n content continues",
			xrefUses: []string{
				"[link-and-xref]",
			},
		},
		{
			input: "something [link][xref]\n content continues",
			xrefUses: []string{
				"[xref]",
			},
		},
		{
			input: "something [link] : (not-a-href)",
			xrefUses: []string{
				"[link]",
			},
		},
		{
			input: "something [link] (this-is-a-href)",
			hrefUses: []string{
				"(this-is-a-href)",
			},
		},
		{
			input: "something [link] \n  (this-is-a-href)\n[link2]\n(href2!)",
			hrefUses: []string{
				"(this-is-a-href)",
				"(href2!)",
			},
		},
		{
			input: "[link]: this-is-a-href",
			xrefDefs: []xrefDef{
				{"[link]", "this-is-a-href"},
			},
		},
		{
			input: "\n\n [link]  :this-is-a-href",
			xrefDefs: []xrefDef{
				{"[link]", "this-is-a-href"},
			},
		},
		{
			input: "\n[xref]",
			xrefUses: []string{
				"[xref]",
			},
		},
		{
			input: "hello\n[TOC]\nhello\n  [toc]\nbut not [toc] here",
			xrefUses: []string{
				"[toc]",
			},
			tocs: []string{
				"[TOC]",
				"[toc]",
			},
		},
		{
			input: `## An example

		- [first]
		- [second]

		[first]: /first/url/here.md
		[second]: /second/url/here.md`,
			xrefUses: []string{
				"[first]",
				"[second]",
			},
			xrefDefs: []xrefDef{
				{"[first]", "/first/url/here.md"},
				{"[second]", "/second/url/here.md"},
			},
		},
		{
			input: "[link-and-xref1]\n[xref1]:def1\n\n\n[link-and-xref2]\n[xref2]:def2",
			xrefUses: []string{
				"[link-and-xref1]",
				"[link-and-xref2]",
			},
			xrefDefs: []xrefDef{
				{"[xref1]", "def1"},
				{"[xref2]", "def2"},
			},
		},
		{
			input: "[toc]\n[toc]",
			tocs: []string{
				"[toc]",
				"[toc]",
			},
		},
		{
			input: `
[this is a valid link][link label]

[link label]: http://google.com`,
			xrefUses: []string{
				"[link label]",
			},
			xrefDefs: []xrefDef{
				{"[link label]", "http://google.com"},
			},
		},
		{
			input: "Linux:  [`/proc/[pid]/stat`](https://man7.org/linux/man-pages/man5/procfs.5.html)",
			hrefUses: []string{
				"(https://man7.org/linux/man-pages/man5/procfs.5.html)",
			},
		},
	}
	for inputNum, ex := range cases {
		t.Run(fmt.Sprintf("input #%d", inputNum), func(t *testing.T) {
			t.Log(strconv.Quote(ex.input))
			var (
				acc       = &recognizerAcc{}
				r         = recognizer{rule: acc}
				tokenizer = newTokenizer(newDoc("filename", strings.NewReader(ex.input)))
				tok       Token
				err       error
			)
			for tok.Kind != EOF {
				tok, err = tokenizer.next()
				if err != nil {
					t.Fatalf("unexpected tokenization error: %s", err)
				}
				r.OnNext(tok)
			}
			// xrefUses
			if len(ex.xrefUses) != len(acc.xrefUses) {
				t.Errorf("len(xrefUses): expected=%d, actual=%d", len(ex.xrefUses), len(acc.xrefUses))
			} else {
				for i := 0; i < len(ex.xrefUses); i++ {
					if acc.xrefUses[i] != ex.xrefUses[i] {
						t.Errorf("xrefUses[%d]: expected=%s, actual=%s", i, ex.xrefUses[i], acc.xrefUses[i])
					}
				}
			}
			// hrefUses
			if len(ex.hrefUses) != len(acc.hrefUses) {
				t.Errorf("len(hrefUses): expected=%d, actual=%d", len(ex.hrefUses), len(acc.hrefUses))
			} else {
				for i := 0; i < len(ex.hrefUses); i++ {
					if acc.hrefUses[i] != ex.hrefUses[i] {
						t.Errorf("hrefUses[%d]: expected=%s, actual=%s", i, ex.hrefUses[i], acc.hrefUses[i])
					}
				}
			}
			// xrefDefs
			if len(ex.xrefDefs) != len(acc.xrefDefs) {
				t.Errorf("len(xrefDefs): expected=%d, actual=%d", len(ex.xrefDefs), len(acc.xrefDefs))
			} else {
				for i := 0; i < len(ex.xrefDefs); i++ {
					if acc.xrefDefs[i].xref != ex.xrefDefs[i].xref {
						t.Errorf("xrefDefs[%d]: expected.xref=%s, actual.xref=%s", i, ex.xrefDefs[i].xref, acc.xrefDefs[i].xref)
					}
					if acc.xrefDefs[i].href != ex.xrefDefs[i].href {
						t.Errorf("xrefDefs[%d]: expected.href=%s, actual.href=%s", i, ex.xrefDefs[i].href, acc.xrefDefs[i].href)
					}
				}
			}
		})
	}
}
