package glog

import (
	"bytes"
	"strings"

	"github.com/gookit/color"
)

var (
	// Info color style
	StyleInfo    = &color.Style{color.OpReset, color.Green}
	StyleWarn    = &color.Style{color.OpBold, color.Yellow}
	StyleError   = &color.Style{color.OpBold, color.Red}
	StyleBlue    = &color.Style{color.OpBold, color.Blue}    //蓝色
	StyleMagenta = &color.Style{color.OpBold, color.Magenta} //品红
	StyleCyan    = &color.Style{color.OpReset, color.Cyan}   //青色
)

func min(args ...int) int {
	t := -1
	for _, arg := range args {
		if arg >= 0 && (arg < t || t == -1) {
			t = arg
		}
	}
	return t
}

var hiddenType = make(map[string]bool)

func SetSubTypeHidden(subTypes ...string) {
	if len(subTypes) > 0 {
		for _, subType := range subTypes {
			hiddenType[subType] = true
		}
	}
}

func SetSubTypeShow(subTypes ...string) {
	if len(subTypes) > 0 {
		for _, subType := range subTypes {
			delete(hiddenType, subType)
		}
	}
}

// <i>content</i>: info
// <w>content</w>: warn
// <e>content</e>: error
// <b>content</b>: blue
// <m>content</m>: magenta
// <c>content</c>: cyan
func osStdoutWrite(s Severity, subType string, data []byte) {
	for st, _ := range hiddenType {
		if subType == st {
			return
		}
	}
	switch s {
	case DebugLog:
		StyleCyan.Print(subType + " ")
		StyleCyan.Print("DBG")
	case InfoLog:
		StyleInfo.Print(subType + " ")
		StyleInfo.Print("INF")
	case WarningLog:
		StyleWarn.Print(subType + " ")
		StyleWarn.Print("WAR")
	case ErrorLog:
		StyleError.Print(subType + " ")
		StyleError.Print("ERR")
	case FatalLog:
		StyleError.Print(subType + " ")
		StyleError.Print("FAT")
	case OtherLog:
		StyleCyan.Print(subType + " ")
		StyleCyan.Print("OTR")
	default:
	}

	ds := string(data)
LABEL_LOOP:
	for {

		ie := strings.Index(ds, "<e>")
		iw := strings.Index(ds, "<w>")
		ii := strings.Index(ds, "<i>")
		ib := strings.Index(ds, "<b>")
		im := strings.Index(ds, "<m>")
		ic := strings.Index(ds, "<c>")
		i := min(ie, iw, ii, ib, im, ic)
		if i < 0 {
			break
		}
		je := strings.Index(ds, "</e>")
		jw := strings.Index(ds, "</w>")
		ji := strings.Index(ds, "</i>")
		jb := strings.Index(ds, "</b>")
		jm := strings.Index(ds, "</m>")
		jc := strings.Index(ds, "</c>")
		j := min(je, jw, ji, jb, jm, jc)
		if j < 0 || j < (i+3) {
			break
		}
		switch ds[i+1] {
		case 'i':
			color.Print(ds[:i])
			StyleInfo.Print(ds[i+3 : j])
			ds = ds[j+4:]
		case 'w':
			color.Print(ds[:i])
			StyleWarn.Print(ds[i+3 : j])
			ds = ds[j+4:]
		case 'e':
			color.Print(ds[:i])
			StyleError.Print(ds[i+3 : j])
			ds = ds[j+4:]
		case 'b':
			color.Print(ds[:i])
			StyleBlue.Print(ds[i+3 : j])
			ds = ds[j+4:]
		case 'm':
			color.Print(ds[:i])
			StyleMagenta.Print(ds[i+3 : j])
			ds = ds[j+4:]
		case 'c':
			color.Print(ds[:i])
			StyleCyan.Print(ds[i+3 : j])
			ds = ds[j+4:]
		default:
			break LABEL_LOOP
		}
	}
	color.Print(ds)
}

func osStdoutWriteNoStyle(data []byte) {
	color.Print(string(data))
}

func filterStdout(data []byte) []byte {
	data = bytes.Replace(data, []byte{'<', 'e', '>'}, nil, -1)
	data = bytes.Replace(data, []byte{'<', 'w', '>'}, nil, -1)
	data = bytes.Replace(data, []byte{'<', 'i', '>'}, nil, -1)
	data = bytes.Replace(data, []byte{'<', '/', 'e', '>'}, nil, -1)
	data = bytes.Replace(data, []byte{'<', '/', 'w', '>'}, nil, -1)
	data = bytes.Replace(data, []byte{'<', '/', 'i', '>'}, nil, -1)
	return data
}
