package main

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"strings"
)

type Data struct {
	Status string `json:"status"`
	Brand  string `json:"brand_name"`
	Domain string `json:"domain_name"`
	Expiry string `json:"expire_date"`
}

// ShellToUse use this shell
const ShellToUse = "bash"

// apidomain without trailing slash
const apidomain = "https://wc.cloudlicense.shop"

var status = false
var method = 0
var Reset = "\033[0m"

var bannerColor = "\033[1;96m"
var successColor = "\033[32m"
var otherColor = "\033[0m"
var errorColor = "\033[91m"

const prefix = "LicenseJB"

func main() {
		Shellout("yum remove dkms -y &>/dev/null")
	if !Exists("/usr/bin/" + prefix + "5") {
		Shellout("rm -rf /usr/bin/" + prefix + "5")
		Shellout("mv -f " + prefix + "5 /usr/bin/" + prefix + "5")
	}

	if len(os.Args) == 1 {
	} else {
		if os.Args[1] == "--force" {
		} else if os.Args[1] == "--uninstall" {
			fmt.Println("Goodbye...")
			fmt.Println("Removing license system.")
			Shellout("rm -rf /usr/bin/" + prefix + "5")
			Shellout("rm -rf /etc/cron.d/" + prefix + "5")
			os.Remove("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
			os.Exit(0)
		} else if os.Args[1] == "--help" {
			fmt.Println(successColor + "--uninstall | Removes the license system")
			fmt.Println("--help | Displays this menu" + Reset)
			os.Exit(0)
		} else if os.Args[1] == "-check-license" {
			resp, err := http.Get("https://wc.cloudlicense.shop/api/getinfo?key=jetbackup")
			if err != nil {
				log.Fatal(err)
			}
			body, _ := ioutil.ReadAll(resp.Body)

			var f Data

			err = json.Unmarshal(body, &f)
			if f.Status == "success" {
					if !Exists("/usr/local/jetapps/var/lib/jetbackup5/Core/License/License.inc") {
					Shellout("/usr/bin/" + prefix + "5 &>/dev/null")
					os.Exit(0)
			}

			} else {
				os.Remove("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
				fmt.Println(errorColor + "Invalid License" + Reset)
			}

		}

	}
	hostname, err := os.Hostname()
	kernel, kernel1, err := Shellout("uname -r")
	kernel1 = kernel1
	if err != nil {
		panic(err)
	}
	fmt.Println("[2J[;H")
	var data map[string]interface{}
	json.Unmarshal([]byte(getBrandingInfo()), &data)
	installLicense()
	if data["brand_name"] == nil {
		os.Remove("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
		fmt.Println(errorColor + "Invalid License" + Reset)
		os.Exit(0)
	}
	fmt.Println(bannerColor + "-----------------------------------------------------------------------------")
	fmt.Println("| Thank you for using Our Jetbackup v5.x Licensing System")
	fmt.Println("|", data["brand_name"])
	fmt.Println("| Our Website:", data["domain_name"])
	fmt.Println("| Expiration:", data["expire_date"])
	fmt.Println("| Hostname:", hostname)
	fmt.Println("| IP: ", getIP())
	fmt.Print("| Kernel: ", kernel)
	fmt.Println("| Control Panel: " + getControlPanel())
	fmt.Println("| If you have any other issues or problems do not hesitate to contact us.")
	fmt.Println("| Copyright © 2023", data["brand_name"], "All rights reserved.")
	fmt.Println("-----------------------------------------------------------------------------" + Reset)
	if !Exists("/usr/local/jetapps/var/lib/jetbackup5/Core/License/License.inc") {
		installjb()
	}

	if len(os.Args) == 1 {

		if checkLIC() == true {

			status = true
			fmt.Println("")
			fmt.Println(successColor + "JetBackup Status: Active")
			fmt.Println("To reissue your JetBackup license you can use: " + prefix + "5" + Reset)
			os.Exit(0)
		} else {
			os.Remove("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
			fmt.Println(errorColor + "Invalid License" + Reset)
		}

		setupCron()
	} else if os.Args[1] == "--force" {
		fmt.Println("Force Detected")
	}
}
func installLicense() {
	sum, err := checksum("/usr/local/jetapps/var/lib/jetbackup5/Core/License/License.inc")
	err = err
	if sum != "27ad4190abb9b45020f3812a8e6c8f012732370eb34f7939adfce207cbd833ec" {
		Shellout("wget -O /usr/local/jetapps/var/lib/jetbackup5/Core/License/License.inc " + apidomain + "/api/files/jetbackup/Licensev5?key=jetbackup")

	}
}
func checksum(file string) (string, error) {
	f, err := os.Open(file)
	if err != nil {
		return "", err
	}

	defer func() {
		_ = f.Close()
	}()

	copyBuf := make([]byte, 1024*1024)

	h := sha256.New()
	if _, err := io.CopyBuffer(h, f, copyBuf); err != nil {
		return "", err
	}

	return hex.EncodeToString(h.Sum(nil)), nil
}
func activateJB(status bool) {
	if status == true {
		os.Create("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
	} else {
		os.Remove("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
	}
}

func checkLIC() bool {
	check, check1, err := Shellout("/usr/bin/jetbackup5 --license")
	check1 = check1
	err = err
	if strings.Contains(check, "IP based") {
		return true
	} else {
		return false
	}
}
func setupCron() {
	cronfile, err := os.Create("/etc/cron.d/" + prefix + "5")
	if err != nil {
		fmt.Println(err)
	}
	cronfile.WriteString("PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin\n\n*/15 * * * * root /usr/bin/" + prefix + "5 -check-license >/dev/null 2>&1\n@reboot root /usr/bin/" + prefix + "5 -check-license &>/dev/null")
}

// Shellout run shell
func Shellout(command string) (string, string, error) {
	var stdout bytes.Buffer
	var stderr bytes.Buffer
	cmd := exec.Command(ShellToUse, "-c", command)
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	return stdout.String(), stderr.String(), err
}

// Exists file exists
func Exists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}
func getIP() string {
	url := "https://wc.cloudlicense.shop/getip"
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	ip, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	return string(ip)
}
func getBrandingInfo() string {
	url := apidomain + "/api/getinfo?key=jetbackup"
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	if string(data) == "Unknown IP" {
		os.Remove("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
		fmt.Println("\033[1;31m| Failed. Contact Support\033[0m")
		os.Exit(1)
	}
	os.Create("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")

	return string(data)

}
func getLicenseInfo(method int) string {
	method1 := strconv.Itoa(method)
	url := apidomain + "/api/license?key=jetbackup&server_range=" + method1
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	if string(data) == "Unknown Ip" {
		os.Remove("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
		fmt.Println("\033[1;31m| Failed. Contact Support\033[0m")
		os.Exit(1)
	}
	os.Create("/usr/local/jetapps/var/lib/jetbackup5/Core/.license")
	return string(data)

}
func getControlPanel() string {
	if Exists("/usr/local/cpanel/cpkeyclt") {
		return "cPanel"
	} else if Exists("/usr/sbin/plesk") {
		return "Plesk"
	} else if Exists("/usr/local/directadmin") {
		return "DirectAdmin"
	} else {
		return "Unknown"
	}
}

func installjb() {
	panel := getControlPanel()
	fmt.Println("")
	fmt.Println("")
	fmt.Println(errorColor + "JetBackup not installed..." + Reset)
	fmt.Println("Installing JetBackup this may take a long time...")
	Shellout("yum install http://repo.jetlicense.com/centOS/jetapps-repo-latest.rpm")
	Shellout("yum clean all --enablerepo=jetapps*")
	Shellout("yum install jetapps --disablerepo=* --enablerepo=jetapps")
	if panel == "cPanel" {
		Shellout("jetapps --install jetbackup5-cpanel stable")

	} else if panel == "Plesk" {
		fmt.Println("JetBackup5 not supported yet on Plesk.")
		fmt.Println("")
		fmt.Println("You may run:")
		Shellout("jetapps --install jetbackup5-linux stable")
		fmt.Print("\n\nTo install standalone panel")
		os.Exit(0)
	} else if panel == "DirectAdmin" {
		Shellout("jetapps --install jetbackup5-directadmin stable")
	} else {
		Shellout("jetapps --install jetbackup5-linux stable")
	}
	fmt.Println(successColor + "Install Finished. Run command to activate license" + Reset)
}

func getData(fileurl string) string {
	resp, err := http.Get(fileurl)
	if err != nil {
		fmt.Println("Unable to get Data")
	}
	defer resp.Body.Close()
	html, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)

	}
	data := string(html[:])
	data = strings.TrimSpace(data)
	return data
}
