package main

import (
	"fmt"
	"log"
	"net/http"
	"encoding/json"
	"io/ioutil"
	"os"
)

type InboxContent struct {
//	AtContext		string `json:"@context"`
	Actor			string `json:"actor"`
	Cc			[]string `json:"cc"`
	Context			string `json:"content"`
	Id			string `json:"id"`
	//Object			string `json:"object"`
	Published		string `json:"published"`
	To			[]string `json:"to"`
	Type			string `json:"type"`
}

func hostmeta(w http.ResponseWriter, r *http.Request) {
	fmt.Println("PATH --> ", r.URL.Path)
	host := r.Host
	xml := "<?xml version=\"1.0\" encoding=\"UTF-8\"?><XRD xmlns=\"http://docs.oasis-open.org/ns/xri/xrd-1.0\"><Link rel=\"lrdd\" template=\"https://" + host + "/.well-known/webfinger?resource={uri}\" type=\"application/xrd+xml\" /></XRD>"
	w.Header().Set("Content-Type", "application/xrd+xml")
	fmt.Fprintf(w, xml)
}

func webfinger(w http.ResponseWriter, r *http.Request) {
	fmt.Println("PATH --> ", r.URL.Path)
	host := r.Host

	webfingermap := make(map[string]interface{})
	webfingermap["subject"] = "acct:fedilogue@" + host
	webfingermap["aliases"] = []string{"https://" + host + "/users/fedilogue"}
	link0 := make(map[string]string)
	link0["rel"] = "http://webfinger.net/rel/profile-page"
	link0["type"] = "text/html"
	link0["href"] = "https://" + host + "/users/fedilogue"
	link1 := make(map[string]string)
	link1["rel"] = "self"
	link1["type"] = "application/activity+json"
	link1["href"] = "https://" + host + "/users/fedilogue"
	link2 := make(map[string]string)
	link2["rel"] = "self"
	link2["type"] = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
	link2["href"] = "https://" + host + "/users/fedilogue"
	link3 := make(map[string]string)
	link3["rel"] = "http://ostatus.org/schema/1.0/subscribe"
	link3["template"] = "https://" + host + "/ostatus_subscribe?acct={uri}"

	links := []map[string]string{link0, link1, link2, link3}
	webfingermap["links"] = links

	webfingerbin, err := json.Marshal(webfingermap)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	webfingerstr := string(webfingerbin)

	query := r.URL.Query()
	resourceRaw, exists := query["resource"]

	if exists {
		resource := resourceRaw[0]
		if resource != "acct:fedilogue@" + host {
			fmt.Println("Writes properly but wrong acct")
			w.Header().Set("Content-Type", "application/json; charset=utf-8")
			fmt.Fprintf(w, webfingerstr)
			return
		}
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		fmt.Fprintf(w, webfingerstr)
		fmt.Println("Writes properly")
	} else {
		fmt.Println(query)
		w.WriteHeader(http.StatusNotFound)
		return
	}
}

func inbox(w http.ResponseWriter, r *http.Request) {
	fmt.Println("PATH --> ", r.URL.Path)

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	var q InboxContent
	err = json.Unmarshal(body, &q)
	fmt.Println(err)
	fmt.Println(q.Cc)
	fmt.Println(q)
}

func users_fedilogue_followers(w http.ResponseWriter, r *http.Request) {
	fmt.Println("PATH --> ", r.URL.Path)
	host := r.Host
	contextlist := map[string]string {"@language":"und"}

	context := []interface{} {"https://www.w3.org/ns/activitystreams", "https://" + host + "/schemas/litepub-0.1.jsonld", contextlist}
	followersmap := make(map[string]interface{})
	followersmap["@context"] = context

	staticjson := "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://" + host + "/schemas/litepub-0.1.jsonld\",{\"@language\":\"und\"}],\"first\":{\"id\":\"https://" + host + "/users/fedilogue/followers?page=1\",\"next\":\"https://" + host + "/users/fedilogue/followers?page=2\",\"orderedItems\":[\"https://mastodon.host/users/federationbot\"],\"partOf\":\"https://" + host + "/users/fedilogue/followers\",\"totalItems\":1,\"type\":\"OrderedCollectionPage\"},\"id\":\"https://" + host + "/users/fedilogue/followers\",\"totalItems\":1,\"type\":\"OrderedCollection\"}"
	//wtf := "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://p.farhan.codes/schemas/litepub-0.1.jsonld\",{\"@language\":\"und\"}],\"first\":{\"id\":\"https://p.farhan.codes/users/fedilogue/followers?page=1\",\"next\":\"https://p.farhan.codes/users/fedilogue/followers?page=2\",\"orderedItems\":[\"https://mastodon.host/users/federationbot\"],\"partOf\":\"https://p.farhan.codes/users/fedilogue/followers\",\"totalItems\":1,\"type\":\"OrderedCollectionPage\"},\"id\":\"https://p.farhan.codes/users/fedilogue/followers\",\"totalItems\":1,\"type\":\"OrderedCollection\"}"

	w.Header().Set("Content-Type", "application/activity+json; charset=utf-8")
	fmt.Fprintf(w, staticjson)
}

func users_fedilogue_following(w http.ResponseWriter, r *http.Request) {
	host := r.Host
	fmt.Println("PATH --> ", r.URL.Path)
	staticjson := "{\"@context\": [\"https://www.w3.org/ns/activitystreams\", \"https://" + host + "/schemas/litepub-0.1.jsonld\", {\"@language\": \"und\"}], \"first\": {\"id\": \"https://" + host + "/users/fedilogue/following?page=1\", \"orderedItems\": [], \"partOf\": \"https://" + host + "/users/fedilogue/following\", \"totalItems\": 0, \"type\": \"OrderedCollectionPage\"}, \"id\": \"https://" + host + "/users/fedilogue/following\", \"totalItems\": 0, \"type\": \"OrderedCollection\"}"
	w.Header().Set("Content-Type", "application/activity+json; charset=utf-8")
	fmt.Fprintf(w, staticjson)
}

func users_fedilogue(w http.ResponseWriter, r *http.Request) {
	fmt.Println("PATH --> ", r.URL.Path)
	host := r.Host

	fmt.Println(r.Host)
	fmt.Println(r.Header["Accept"])

	publickeybin, err := ioutil.ReadFile("keys/public.pem")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	publickeypemstr := string(publickeybin)

	publicKey := map[string]string {"id":"https://" + host + "/users/fedilogue#main-key", "owner": "https://" + host + "/users/fedilogue", "publicKeyPem": publickeypemstr}

	capabilities := map[string]bool{}
	tag := []string{}
	contextlist := map[string]string {"@language":"und"}
	attachment := []string{}
	endpoints := map[string]string {"oauthAuthorizationEndpoint":"https://" + host+ "/oauth/authorize", "oauthRegistrationEndpoint": "https://" + host + "/api/v1/apps", "oauthTokenEndpoint": "https://" + host + "/oauth/token", "sharedInbox": "https://" + host + "/inbox", "uploadMedia": "https://" + host + "/api/ap/upload_media"}

	context := []interface{} {"https://www.w3.org/ns/activitystreams", "https://" + host + "/schemas/litepub-0.1.jsonld", contextlist}
	userjsonmap := make(map[string]interface{})
	userjsonmap["@context"] = context
	userjsonmap["attachment"] = attachment
	userjsonmap["capabilities"] = capabilities
	userjsonmap["discoverable"] = false
	userjsonmap["endpoints"] = endpoints
	userjsonmap["followers"] = "https://" + host + "/users/fedilogue/followers"
	userjsonmap["following"] = "https://" + host + "/users/fedilogue/following"
	userjsonmap["id"] = "https://" + host + "/users/fedilogue"
	userjsonmap["inbox"] = "https://" + host + "/users/fedilogue/inbox"
	userjsonmap["manuallyApprovesFollowers"] = false
	userjsonmap["name"] = "Fedilogue Mass Follower"
	userjsonmap["outbox"] = "https://" + host + "/users/fedilogue/outbox"
	userjsonmap["preferredUsername"] = "fedilogue"
	userjsonmap["publicKey"] = publicKey
	userjsonmap["summary"] = ""
	userjsonmap["tag"] = tag
	userjsonmap["type"] = "Person"
	userjsonmap["uri"] = "https://" + host + "/users/fedilogue"

	userjsonbin, err := json.Marshal(userjsonmap)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	userjsonstr := string(userjsonbin)
	w.Header().Set("Content-Type", "application/activity+json; charset=utf-8")
	fmt.Fprintf(w, userjsonstr)
}

func errorHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Println("404 --> ", r.URL.Path)
}

func webmain(reportPostChan chan ReportPost) {
	http.HandleFunc("/.well-known/webfinger", webfinger)
	http.HandleFunc("/.well-known/host-meta", hostmeta)
	http.HandleFunc("/inbox", inbox)
	http.HandleFunc("/users/fedilogue", users_fedilogue)
	http.HandleFunc("/users/fedilogue/followers", users_fedilogue_followers)
	http.HandleFunc("/users/fedilogue/following", users_fedilogue_following)
	http.HandleFunc("/", errorHandler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}