package main

import (
	"bytes"
	"fmt"
	"log"
	"unicode"

	"srs.epita.fr/fic-server/admin/sync"
	"srs.epita.fr/fic-server/libfic"
	lib "srs.epita.fr/fic-server/repochecker/grammalecte/lib"
)

func GrammalecteCheckKeyFlag(flag *fic.FlagKey, raw string, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
	if !isRecognizedLanguage(exercice.Language) {
		return
	}

	label, _, _, _ := flag.AnalyzeFlagLabel()
	for _, err := range grammalecte("label ", label, -1, exceptions, &CommonOpts) {
		if e, ok := err.(lib.GrammarError); ok && e.RuleId == "poncfin_règle1" {
			continue
		}

		errs = append(errs, err)
	}

	if len(flag.Help) > 0 {
		errs = append(errs, grammalecte("help ", flag.Help, -1, exceptions, &CommonOpts)...)
	}

	return
}

func GrammalecteCheckFlagChoice(choice *fic.FlagChoice, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
	if isRecognizedLanguage(exercice.Language) {
		errs = append(errs, grammalecte("label ", choice.Label, -1, exceptions, &CommonOpts)...)
	}

	if len(errs) == 0 && !unicode.IsUpper(bytes.Runes([]byte(choice.Label))[0]) && !exceptions.HasException(":label_majuscule") {
		errs = append(errs, fmt.Errorf("%q nécessite une majuscule (:label_majuscule)", choice.Label))
	}

	return
}

func GrammalecteCheckHint(hint *fic.EHint, exercice *fic.Exercice, exceptions *sync.CheckExceptions) (errs []error) {
	if len(hint.Title) > 0 {
		if isRecognizedLanguage(exercice.Language) {
			errs = append(errs, grammalecte("title ", hint.Title, -1, exceptions, &CommonOpts)...)
		}
		if len(errs) == 0 && !unicode.IsUpper(bytes.Runes([]byte(hint.Title))[0]) && !exceptions.HasException(":title_majuscule") {
			errs = append(errs, fmt.Errorf("%q nécessite une majuscule (:title_majuscule)", hint.Title))
		}
	}

	// Hint content are checked through GrammalecteCheckMDText, no need to check them

	return
}

func GrammalecteCheckGrammar(data interface{}, exceptions *sync.CheckExceptions) []error {
	if s, ok := data.(struct {
		Str      string
		Language string
	}); ok {
		if !isRecognizedLanguage(s.Language) {
			return nil
		}

		return grammalecte("", s.Str, 0, exceptions, &CommonOpts)
	} else {
		log.Printf("Unknown data given to GrammalecteCheckGrammar: %T", data)
		return nil
	}
}
