import { create } from 'xmlbuilder2';
import { parseISO, formatISO } from 'date-fns/fp';
import { readdir, Dirent, readFile, writeFile } from 'fs';
import { basename, extname } from 'path';
import { promisify } from 'util';
import { join } from 'path';
import matter from 'gray-matter';

const readDirAsync = promisify(readdir);
const readFileAsync = promisify(readFile);
const writeFileAsync = promisify(writeFile);

const postsPath = join(__dirname, '..', 'posts');
const rssPath = join(__dirname, '..', 'public', 'rss.xml');

export interface PostMetadata {
    title: string;
    created: Date;
    abstract: string;
    id: string;
}

export const getPostMetadata = async (postFile: string): Promise<PostMetadata> => {
    const fileContent = await readFileAsync(join(postsPath, postFile), {
        encoding: 'utf8'
    });

    const result = matter(fileContent);
    const postId = basename(postFile, extname(postFile));

    return {
        title: result.data.title,
        abstract: result.data.abstract,
        created: parseISO(result.data.created),
        id: postId
    };
};

export const getPostsMetadata = async (): Promise<PostMetadata[]> => {
    const dirContent: Dirent[] = await readDirAsync(postsPath, {
        withFileTypes: true,
        encoding: 'utf8'
    });

    return Promise.all(
        dirContent
            .filter(entry => entry.isFile())
            .map((entry) => {
                console.log(`Reading meta for ${entry.name}`);
                return getPostMetadata(entry.name);
            })
    );
};

(async () => {
    console.log('Reading posts metadata...');
    const postsData = await getPostsMetadata();
    postsData.sort((a, b) => {
        return a > b ? 1 : -1;
    });
    console.log('Generating xml content...');
    const data = {
        rss: {
            '@version': '2.0',
            channel: {
                title: 'Sosnowski.dev - Personal Blog',
                link: 'https://sosnowski.dev',
                description: `Hi! I'm Damian. I'm an Engineering Manager in OLX, certified AWS Architect Associate and a technology geek. Welcome to my blog!`,
                item: postsData.map(meta => {
                    return {
                        title: meta.title,
                        link: `https://sosnowski.dev/post/${meta.id}`,
                        description: meta.abstract,
                        pubDate: formatISO(meta.created)
                    };
                })
            }
        }
    };

    const doc = create(data);
    const xml = doc.end({ prettyPrint: true });
    console.log('Saving file...');
    await writeFileAsync(rssPath, xml, { encoding: 'utf8' });
})();