package main

import (
	"fmt"
	"strings"
)

type killfileItem struct {
	Kdomain  string
	Ksource  string
	Kconfigs stringarray
}

var bKillChannel chan killfileItem
var bWhiteListChannel chan killfileItem

func init() {

	bKillChannel = make(chan killfileItem, 1024)
	bWhiteListChannel = make(chan killfileItem, 1024)
	fmt.Println("Initializing kill channel engine.")

	go bWriteKillThread()
	go bWriteWhiteListThread()

}

func bWriteKillThread() {

	for item := range bKillChannel {

		alreadyInSomeDB := false

		for _, config := range item.Kconfigs {
			if !alreadyInSomeDB {
				alreadyInSomeDB = domainInKillfile(item.Kdomain, config)
			}
			writeInKillfile(item.Kdomain, item.Ksource, config)
		}
		if !alreadyInSomeDB {
			incrementStats("BL domains from "+item.Ksource, 1)
			incrementStats("TOTAL", 1)
		}

	}

}

//DomainKill stores a domain name inside the killfile
func DomainKill(s, durl string, configs stringarray) {

	if len(s) > 2 {

		s = strings.ToLower(s)

		var k killfileItem

		k.Kdomain = s
		k.Ksource = durl
		k.Kconfigs = configs

		bKillChannel <- k

	}

}

func writeInKillfile(key, value string, config string) {

	stK := []byte(key)
	stV := []byte(value)

	MyZabovKDB := MyZabovKDBs[config]
	err := MyZabovKDB.Put(stK, stV, nil)
	if err != nil {
		fmt.Println("Cannot write to Killfile DB: ", err.Error())
	}

}

func domainInKillfile(domain string, config string) bool {

	s := strings.ToLower(domain)

	MyZabovKDB := MyZabovKDBs[config]
	has, err := MyZabovKDB.Has([]byte(s), nil)
	if err != nil {
		fmt.Println("Cannot read from Killfile DB: ", err.Error())
	}

	return has

}

func bWriteWhiteListThread() {

	for item := range bWhiteListChannel {

		alreadyInSomeDB := false

		for _, config := range item.Kconfigs {
			if !alreadyInSomeDB {
				alreadyInSomeDB = domainInWhiteListfile(item.Kdomain, config)
			}
			writeInWhiteListfile(item.Kdomain, item.Ksource, config)
		}
		if !alreadyInSomeDB {
			incrementStats("WL domains from "+item.Ksource, 1)
			incrementStats("WL TOTAL", 1)
		}

	}

}

//DomainWhiteList stores a domain name inside the killfile
func DomainWhiteList(s, durl string, configs stringarray) {

	if len(s) > 2 {

		s = strings.ToLower(s)

		var k killfileItem

		k.Kdomain = s
		k.Ksource = durl
		k.Kconfigs = configs

		bWhiteListChannel <- k

	}

}

func writeInWhiteListfile(key, value string, config string) {

	stK := []byte(key)
	stV := []byte(value)

	MyZabovWLDB := MyZabovWLDBs[config]
	err := MyZabovWLDB.Put(stK, stV, nil)
	if err != nil {
		fmt.Println("Cannot write to Whitelist DB: ", err.Error())
	}

}
func domainInWhiteListfile(domain string, config string) bool {

	s := strings.ToLower(domain)

	MyZabovWLDB := MyZabovWLDBs[config]
	has, err := MyZabovWLDB.Has([]byte(s), nil)
	if err != nil {
		fmt.Println("Cannot read from Whitelist DB: ", err.Error())
	}

	return has

}
