import express, { Router, Request, Response } from "express";
import { Page, PostMetadata } from "../metadata";
import { ArticleObject } from "./activity";
import Article from "../entity/Article";
import { getConnection } from "typeorm";
import uuidv4 from "uuid/v4";

const domain = process.env.DOMAIN;

export async function setup(posts: Page[]) {
	const repository = getConnection().getRepository(Article);
	const allPosts = await repository.find();
	for (const post of posts) {
		const postMeta = <PostMetadata>post.metadata;
		if (allPosts.some((p) => p.id === postMeta.permalink)) {
			continue;
		}
		const articleObject = {
			"@context": [
				"https://www.w3.org/ns/activitystreams",
			],
			"type": "Article",
			"id": `https://${domain}${post.metadata.permalink}`,
			"published": (<Date>postMeta.date).toISOString(),
			"inReplyTo": null,
			"conversation": `https://${domain}/ap/conversation/${uuidv4()}`,
			"url": `https://${domain}${postMeta.permalink}`,
			"attributedTo": `https://${domain}/ap/actor`,
			"to": [
				"https://www.w3.org/ns/activitystreams#Public"
			],
			"cc": [
				`https://${domain}/ap/actor/followers`
			],
			"name": postMeta.title,
			"content": post.text
		};
		const article = new Article();
		article.id = postMeta.permalink;
		article.articleObject = articleObject;
		article.conversation = articleObject.conversation;
		article.hasFederated = false;
		await getConnection().manager.save(article);
	}
}

export async function toFederate(): Promise<[string, ArticleObject][]> {
	return new Promise(async (resolve, reject) => {
		const articles: Article[] = await getConnection().createQueryBuilder().select("article").from(Article, "article").where("article.hasFederated = :hasFederated", { hasFederated: false }).getMany();
		
		let result: [string, ArticleObject][] = [];
		articles.forEach(it => {
			result.push([it.id, it.articleObject]);
		});
		resolve(result);
	});
}

export function route(router: Router) {
	router.use("/:year/:slug/", async (req, res, next) => {
		const best = req.accepts(["text/html", "application/activity+json"]);
		if (best === "text/html") {
			next();
		} else if (best === "application/activity+json") {
			const id = `/${req.params.year}/${req.params.slug}/`;
			const repository = getConnection().getRepository(Article);
			try {
				const article = await repository.findOne(id);
				res.type("application/activity+json").json(article.articleObject).end();
			} catch (err) {
				res.status(500).end(err);
			}

		} else {
			res.status(415).end("No acceptable content-type given. text/html or application/activity+json are supported");
		}
	});
}
