package sync

import (
	"fmt"
	"path/filepath"
	"strings"

	"srs.epita.fr/fic-server/libfic"
)

type CheckExceptions map[string]string

func (c *CheckExceptions) GetExerciceExceptions(e *fic.Exercice) *CheckExceptions {
	return c.GetFileExceptions(filepath.Base(e.Path))
}

func (c *CheckExceptions) GetFileExceptions(paths ...string) *CheckExceptions {
	ret := CheckExceptions{}

	if c != nil {
		for k, v := range *c {
			cols := strings.SplitN(k, ":", 2)
			if len(cols) < 2 {
				continue
			}

			for _, path := range paths {
				if strings.HasPrefix(cols[0], path) {
					k = strings.TrimPrefix(k, path)

					if strings.HasPrefix(k, "/") {
						k = strings.TrimPrefix(k, "/")
					}

					ret[k] = v
					break
				} else if eval, err := filepath.Match(cols[0], path); err == nil && eval {
					ret[k] = v
					break
				}
			}
		}
	}

	// Ignore redondances in resolution.md
	if len(paths) > 0 && paths[0] == "resolution.md" {
		ret["resolution.md:*:redondances_paragraphe"] = "automatic"
	}

	return &ret
}

func (c *CheckExceptions) Filter2ndCol(str string) *CheckExceptions {
	if c == nil {
		return nil
	}

	ret := CheckExceptions{}

	for k, v := range *c {
		cols := strings.SplitN(k, ":", 3)
		if len(cols) < 2 {
			continue
		}

		if cols[1] == "spelling" {
			ret[k] = v
		} else if eval, err := filepath.Match(cols[1], str); err == nil && eval {
			ret[k] = v
		}
	}

	return &ret
}

func (c *CheckExceptions) HasException(ref string) bool {
	if c == nil {
		return false
	}

	for k, _ := range *c {
		if strings.HasSuffix(k, ref) {
			return true
		}
	}

	return false
}

func ParseExceptionString(fexcept string, exceptions *CheckExceptions) *CheckExceptions {
	if exceptions == nil {
		exceptions = &CheckExceptions{}
	}

	for n, line := range strings.Split(fexcept, "\n") {
		(*exceptions)[strings.TrimSpace(line)] = fmt.Sprintf("repochecker-ack.txt:%d", n+1)
	}

	return exceptions
}

func LoadThemeException(i Importer, th *fic.Theme) (exceptions *CheckExceptions) {
	if th == nil {
		return
	}

	if fexcept, err := GetFileContent(i, filepath.Join(th.Path, "repochecker-ack.txt")); err == nil {
		return ParseExceptionString(fexcept, nil)
	}

	return
}

func LoadExerciceException(i Importer, th *fic.Theme, e *fic.Exercice, th_exceptions *CheckExceptions) (exceptions *CheckExceptions) {
	if th_exceptions == nil {
		th_exceptions = LoadThemeException(i, th)
	}

	exceptions = th_exceptions.GetExerciceExceptions(e)

	if fexcept, err := GetFileContent(i, filepath.Join(e.Path, "repochecker-ack.txt")); err == nil {
		return ParseExceptionString(fexcept, exceptions)
	}

	return
}
