package matcher

import (
	"log/slog"
	"os"
	"testing"

	"gopkg.in/yaml.v3"
)

func TestUnmarshalFromYaml(t *testing.T) {
	yamlStr := `
extractors:
  label1: "{{ index .Fields.Components 0 }}"
  label2: "{{ (.Fields.MoreFields.customfield_123 | tryUnmarshalJson).jsonKey1 }}"
  label3: "plain"
  negative: "with out '!'"
routes:
  - receiver: 1
    continue: true
    match:
      label1: value1
      label2: option1|option2|option3
  - receiver: 1
    match:
      label3: value2
  - receiver: 2
    match:
      "!negative": value3
`
	var m Matcher
	err := yaml.Unmarshal([]byte(yamlStr), &m)
	if err != nil {
		t.Error(err)
	}
	t.Log(m)
}

func TestUnmarshalFromYamlNoEnoughExtracotrs(t *testing.T) {
	yamlStr := `
extractors:
  label1: "{{ index .Fields.Components 0 }}"
  label2: "{{ (.Fields.MoreFields.customfield_123 | tryUnmarshalJson).jsonKey1 }}"
  # label3: "plain"
  negative: "with out '!'"
routes:
  - receiver: 1
    continue: true
    match:
      label1: value1
      label2: option1|option2|option3
  - receiver: 1
    match:
      label3: value2
  - receiver: 2
    match:
      "!negative": value3
`
	var m Matcher
	err := yaml.Unmarshal([]byte(yamlStr), &m)
	if err != nil {
		t.Error(err)
	}
	err = m.valid()
	t.Log(err)
	if err == nil {
		t.Error("'Valid' did not find errors")
	}
}

func TestUnmarshalFromYamlBadFormatOfTmpl(t *testing.T) {
	yamlStr := `
extractors:
  label1: "{{ index .Fields.Components 0 "
  label2: "{{ (.Fields.MoreFields.customfield_123 | unmarshalJson).jsonKey1 }}"
  label3: "plain"
  negative: "with out '!'"
routes:
  - receiver: 1
    continue: true
    match:
      label1: value1
      label2: option1|option2|option3
  - receiver: 1
    match:
      label3: value2
  - receiver: 2
    match:
      "!negative": value3
`
	var m Matcher
	err := yaml.Unmarshal([]byte(yamlStr), &m)
	t.Log(err)
	if err == nil {
		t.Error("did not find bad format")
	}
}

func TestUnmarshalFromYamlBadFormatOfRegexp(t *testing.T) {
	yamlStr := `
extractors:
  label1: "{{ index .Fields.Components 0 }}"
  label2: "{{ (.Fields.MoreFields.customfield_123 | unmarshalJson).jsonKey1 }}"
  label3: "plain"
  negative: "with out '!'"
routes:
  - receiver: 1
    continue: true
    match:
      label1: (value1
      label2: option1|option2|option3
  - receiver: 1
    match:
      label3: value2
  - receiver: 2
    match:
      "!negative": value3
`
	var m Matcher
	err := yaml.Unmarshal([]byte(yamlStr), &m)
	t.Log(err)
	if err == nil {
		t.Error("did not find bad format")
	}
}

func TestTransmuteReceiver(t *testing.T) {
	yamlStr := `
extractors:
  label1: "label1"
  negative: "negative"
routes:
  - receiver: 1
    continue: true
    match:
      label1: label1
  - receiver: 1
    match:
      label1: value2
  - receiver: 2
    match:
      "!negative": positive
`
	var m Matcher
	err := yaml.Unmarshal([]byte(yamlStr), &m)
	if err != nil {
		t.Error(err)
	}
	m.logger = slog.New(slog.NewTextHandler(os.Stdout, nil))
	rs, err := m.Match(nil)
	if err != nil {
		t.Error(err)
	}
	intRs, err := rs.TryToIntSlice()
	if err != nil {
		t.Error(err)
	}
	t.Log(intRs)
}

func TestTransmuteReceiverString(t *testing.T) {
	yamlStr := `
extractors:
  label1: "label1"
  negative: "negative"
routes:
  - receiver: abc
    continue: true
    match:
      label1: label1
  - receiver: def
    match:
      label1: value2
  - receiver: ghi
    match:
      "!negative": positive
`
	var m Matcher
	err := yaml.Unmarshal([]byte(yamlStr), &m)
	if err != nil {
		t.Error(err)
	}
	m.logger = slog.New(slog.NewTextHandler(os.Stdout, nil))
	rs, err := m.Match(nil)
	if err != nil {
		t.Error(err)
	}
	stringRs, err := rs.TryToStringSlice()
	if err != nil {
		t.Error(err)
	}
	t.Log(stringRs)
}

func TestFunctions(t *testing.T) {
	yamlStr := `
extractors:
  daytime: "{{if isDayTime}}day{{else}}night{{end}}"
routes:
  - receiver: abc
    continue: true
    match:
      daytime: day
  - receiver: def
    match:
      daytime: night
`
	var m Matcher
	err := yaml.Unmarshal([]byte(yamlStr), &m)
	if err != nil {
		t.Error(err)
	}
	m.logger = slog.New(slog.NewTextHandler(os.Stdout, nil))
	rs, err := m.Match(nil)
	if err != nil {
		t.Error(err)
	}
	stringRs, err := rs.TryToStringSlice()
	if err != nil {
		t.Error(err)
	}
	t.Log(stringRs)
}
