/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

const fs = require("fs").promises;
const path = require("path");
const {promisify} = require("util");
const frontMatterParser = require("parser-front-matter");
const parse = promisify(frontMatterParser.parse.bind(frontMatterParser));
const lunrjs = require("lunr");

const contentDirectory = `${__dirname}/site/content`;
const outputDirectory = `${__dirname}/site/static/_gen/indexes`;


async function isDirectoryExists(dirPath) {
  try {
    if ((await fs.stat(dirPath)).isDirectory()) {
      return true;
    }
  } catch {
    return false;
  }
  return false;
}

async function loadPostsWithFrontMatter(postsDirectoryPath) {
  const fileNames = await fs.readdir(postsDirectoryPath);
  const posts = await Promise.all(
    fileNames.map(async(fileName) => {
      let filePath;
      if ((await fs.stat(`${postsDirectoryPath}/${fileName}`)).isFile()) {
        filePath = `${postsDirectoryPath}/${fileName}`;
      } else {
        filePath = `${postsDirectoryPath}/${fileName}/index.md`;
      }
      const fileContent = await fs.readFile(
        filePath,
        "utf8"
      );
      const {content, data} = await parse(fileContent);
      return {
        content: content.slice(0, 3000),
        url: path.parse(fileName).name,
        ...data
      };
    })
  );
  return posts;
}

function makeIndex(posts) {
  return lunrjs(function() {
    this.ref("title");
    this.field("title");
    this.field("description");
    this.field("author");
    this.field("content");
    this.field("tags");
    this.field("url");
    posts.forEach((p) => {
      this.add(p);
    });
  });
}

async function writeJson(filePath, index) {
  await fs.writeFile(filePath, JSON.stringify(index));
  console.log(`Saved ${path.parse(filePath).base} file.`);
}

async function processLanguage(language) {
  console.log(`Processing "${language}" language.`);
  const currentDirectory = `${contentDirectory}/${language}/blog`;
  if (!await isDirectoryExists(currentDirectory)) {
    console.log("No blog posts. Skipping.");
    return;
  }
  const posts = await loadPostsWithFrontMatter(currentDirectory);
  const index = makeIndex(posts);
  const currentOutputDirectory = `${outputDirectory}/${language}`;
  if (!await isDirectoryExists(currentOutputDirectory)) {
    await fs.mkdir(currentOutputDirectory);
  }
  await writeJson(`${currentOutputDirectory}/blog-index.json`, index);
  await writeJson(`${currentOutputDirectory}/blog-posts.json`, posts);
}

async function run() {
  const directoryNames = await fs.readdir(contentDirectory);
  for (const directoryName of directoryNames) {
    await processLanguage(directoryName);
  }
}

run()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error.stack);
    process.exit(1);
  });
