package main

import (
	"compress/gzip"
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

type KeyPress struct {
	Key string `json:"key"`
}

type RateLimiter struct {
	connections map[string]int
	messages    map[string]time.Time
	mutex       sync.RWMutex
}

var limiter = &RateLimiter{
	connections: make(map[string]int),
	messages:    make(map[string]time.Time),
}

var trollingGifBase64 string
var trollingHTML string
var trollingHTMLOnce sync.Once

var curpingFileBase64 string
var curpingFileName string
var curpingFileOnce sync.Once

func (rl *RateLimiter) canConnect(ip string) bool {
	rl.mutex.Lock()
	defer rl.mutex.Unlock()

	if rl.connections[ip] >= 3 {
		return false
	}
	rl.connections[ip]++
	return true
}

func (rl *RateLimiter) canSendMessage(ip string) bool {
	rl.mutex.Lock()
	defer rl.mutex.Unlock()

	lastMessage, exists := rl.messages[ip]
	if exists && time.Since(lastMessage) < 30*time.Millisecond {
		return false
	}
	rl.messages[ip] = time.Now()
	return true
}

func (rl *RateLimiter) disconnect(ip string) {
	rl.mutex.Lock()
	defer rl.mutex.Unlock()

	if rl.connections[ip] > 0 {
		rl.connections[ip]--
	}
}

type gzipResponseWriter struct {
	io.Writer
	http.ResponseWriter
}

func (w gzipResponseWriter) Write(b []byte) (int, error) {
	return w.Writer.Write(b)
}

func gzipHandler(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
			next(w, r)
			return
		}

		gz := gzip.NewWriter(w)
		defer gz.Close()

		w.Header().Set("Content-Encoding", "gzip")
		next(gzipResponseWriter{Writer: gz, ResponseWriter: w}, r)
	}
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
	ip := strings.Split(r.RemoteAddr, ":")[0]

	if !limiter.canConnect(ip) {
		conn, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Printf("WebSocket upgrade error: %v", err)
			return
		}
		conn.WriteJSON(map[string]string{"action": "show_message", "message": "You make too many requests, yk..."})
		conn.Close()
		return
	}

	defer limiter.disconnect(ip)

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Printf("WebSocket upgrade error: %v", err)
		return
	}
	defer conn.Close()

	var buffer string
	var lastPress time.Time

	for {
		var keyPress KeyPress
		err := conn.ReadJSON(&keyPress)
		if err != nil {
			break
		}

		if !limiter.canSendMessage(ip) {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "You make too many requests, yk..."})
			continue
		}

		now := time.Now()
		if now.Sub(lastPress) > 5*time.Second {
			buffer = ""
		}
		lastPress = now

		buffer += keyPress.Key

		if len(buffer) > 20 {
			buffer = buffer[len(buffer)-20:]
		}

		if buffer == "lain" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://fauux.neocities.org"})
			buffer = ""
		} else if buffer == "rabbit" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "wake up, Neo"})
			buffer = ""
		} else if buffer == "whoareu" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/systemxplore"})
			buffer = ""
		} else if buffer == "whoami" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/systemxplore"})
			buffer = ""
		} else if buffer == "whoareyou" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/systemxplore"})
			buffer = ""
		} else if buffer == "answer" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "it must be easy for you, isn't that right?"})
			buffer = ""
		} else if buffer == "answers" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "it must be easy for you, isn't that right?"})
			buffer = ""
		} else if buffer == "noise" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://noiseprotocol.org/"})
			buffer = ""
		} else if buffer == "openbsd" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://openbsd.org/"})
			buffer = ""
		} else if buffer == "linux" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "Linux sucks"})
			buffer = ""
		} else if buffer == "mac" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "Yet another BSD-like OS"})
			buffer = ""
		} else if buffer == "windows" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "Windows ALWAYS sucks"})
			buffer = ""
		} else if buffer == "github" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://codeberg.org/"})
			buffer = ""
		} else if buffer == "status" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "/status"})
			buffer = ""
		} else if buffer == "reddit" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://www.reddit.com/r/openbsd/s/zxEkMj0uaW"})
			buffer = ""
		} else if buffer == "intelme" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "Everything must be free, without tracking"})
			buffer = ""
		} else if buffer == "amdpsp" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "Everything must be free, without tracking"})
			buffer = ""
		} else if buffer == "uefi" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://www.techtarget.com/searchsecurity/news/366618102/ESET-details-UEFI-Secure-Boot-bypass-vulnerability"})
			buffer = ""
		} else if buffer == "trolling" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "/trolling"})
			buffer = ""
		} else if buffer == "club" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/+-eNzwqVM5_U5NDdi"})
			buffer = ""
		} else if buffer == "icmp" {
			conn.WriteJSON(map[string]string{"action": "show_message", "message": "\"Timestamp from icmp data...\" why is there a timestamp in the echo request?"})
			buffer = ""
		} else if buffer == "cursping" {
			conn.WriteJSON(map[string]string{"action": "redirect", "url": "/cursping.zip.tar.gz"})
			buffer = ""
		}
	}
}

func initTrollingHTML() {
	fileContent, err := os.ReadFile("files/trolling.gif")
	if err != nil {
		log.Printf("Error reading file: %v", err)
		fileContent = []byte("File not found")
	}

	trollingGifBase64 = base64.StdEncoding.EncodeToString(fileContent)
	trollingHTML = fmt.Sprintf(`
<!DOCTYPE html>
<html>
<head>
    <title>Trolling</title>
    <style>
        body {
            background-color: #000;
            color: #00ff00;
            font-family: 'Courier New', monospace;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        img {
            max-width: 100%%;
            max-height: 100%%;
        }
    </style>
</head>
<body>
    <img src="data:image/gif;base64,%s" alt="мы делаем небольшой троллинг">
</body>
</html>`, trollingGifBase64)
}

func initCurpingFile() {
	fileContent, err := os.ReadFile("files/cursping.zip.tar.gz")
	if err != nil {
		log.Printf("Error reading curping file: %v", err)
		fileContent = []byte("File not found")
	}

	curpingFileBase64 = base64.StdEncoding.EncodeToString(fileContent)
	curpingFileName = "curping"
}

func trollingHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Header().Set("Server", "0BSD_FOR_EVERYONE")
	w.Header().Set("Cache-Control", "public, max-age=3600")

	trollingHTMLOnce.Do(initTrollingHTML)
	fmt.Fprint(w, trollingHTML)
}

func curpingHandler(w http.ResponseWriter, r *http.Request) {
	curpingFileOnce.Do(initCurpingFile)

	fileData, err := base64.StdEncoding.DecodeString(curpingFileBase64)
	if err != nil {
		http.Error(w, "Error decoding file", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/octet-stream")
	w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", curpingFileName))
	w.Header().Set("Server", "0BSD_FOR_EVERYONE")
	w.Header().Set("Cache-Control", "public, max-age=3600")

	w.Write(fileData)
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	w.Header().Set("Server", "0BSD_FOR_EVERYONE")

	openbsdBirth := time.Date(1995, 10, 1, 0, 0, 0, 0, time.UTC)
	now := time.Now()
	duration := now.Sub(openbsdBirth)

	years := int(duration.Hours() / 8760)
	months := int((duration.Hours() - float64(years*8760)) / 730)
	weeks := int((duration.Hours() - float64(years*8760) - float64(months*730)) / 168)
	hours := int(duration.Hours() - float64(years*8760) - float64(months*730) - float64(weeks*168))
	minutes := int(duration.Minutes()) % 60
	seconds := int(duration.Seconds()) % 60
	milliseconds := int(duration.Milliseconds()) % 1000
	nanoseconds := int(duration.Nanoseconds()) % 1000000

	status := fmt.Sprintf("OpenBSD created: %d:%d:%d:%d:%d:%d:%d:%d\nTimestamp: %d",
		years, months, weeks, hours, minutes, seconds, milliseconds, nanoseconds,
		int(duration.Seconds()))

	fmt.Fprint(w, status)
}

func handler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Header().Set("Server", "0BSD_FOR_EVERYONE")
	w.Header().Set("X-Powered-By", "0BSD_FOR_EVERYONE")
	w.Header().Set("X-Frame-Options", "SAMEORIGIN")
	w.Header().Set("X-Content-Type-Options", "nosniff")

	html := `
<!DOCTYPE html>
<html>
<head>
    <title>0BSD_FOR_EVERYONE</title>
    <style>
        body {
            font-family: 'Courier New', monospace;
            background-color: #000;
            color: #00ff00;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            font-size: 3em;
            text-shadow: 0 0 10px #00ff00;
            position: relative;
        }
        #y{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);color:#ff0000;font-size:1.5em;text-shadow:0 0 10px #ff0000;display:none;z-index:1000}
    </style>
</head>
<body>
    0BSD_FOR_EVERYONE
    <div id="y"></div>
    
    <script>
    (function(){
        var ws=new WebSocket('ws://'+window.location.host+'/ws');
        var buffer='';
        var lastPress=Date.now();
        
        ws.onopen=function(){};
        ws.onmessage=function(e){
            var data=JSON.parse(e.data);
            if(data.action==='redirect')window.location.href=data.url;
            if(data.action==='show_message'){
                var msg=document.getElementById('y');
                msg.textContent=data.message;
                msg.style.display='block';
                setTimeout(function(){msg.style.display='none'},3000);
            }
        };
        
        document.addEventListener('keydown',function(e){
            var now=Date.now();
            if(now-lastPress>5000)buffer='';
            lastPress=now;
            
            buffer+=e.key.toLowerCase();
            if(buffer.length>20)buffer=buffer.slice(-20);
            
            ws.send(JSON.stringify({key:e.key.toLowerCase()}));
        });
    })();
    </script>
</body>
</html>`
	fmt.Fprint(w, html)
}

func main() {
	ports := []string{"1337", "1488", "13373", "33737", "25575", "80", "8080"}

	var wg sync.WaitGroup

	for _, port := range ports {
		wg.Add(1)
		go func(p string) {
			defer wg.Done()
			mux := http.NewServeMux()
			mux.HandleFunc("/", gzipHandler(handler))
			mux.HandleFunc("/ws", wsHandler)
			mux.HandleFunc("/status", gzipHandler(statusHandler))
			mux.HandleFunc("/trolling", gzipHandler(trollingHandler))
			mux.HandleFunc("/cursping.zip.tar.gz", curpingHandler)

			server := &http.Server{
				Addr:         ":" + p,
				Handler:      mux,
				ReadTimeout:  30 * time.Second,
				WriteTimeout: 30 * time.Second,
				IdleTimeout:  60 * time.Second,
			}

			log.Printf("Server started on port %s", p)
			if err := server.ListenAndServe(); err != nil {
				log.Printf("Error on port %s: %v", p, err)
			}
		}(port)
	}

	wg.Wait()
}
