import { SNSEvent, SNSEventRecord } from "aws-lambda";
import * as md5 from "md5";
import { initCommonMiddlewares } from "../middlewares";
import { invokeService } from "./helpers";
const semver2int = require("semver2int");

interface IMessage {
  version: string;
  description: string;
  execute: {
    id: string;
  };
  readme: {
    id: string;
  };
  superuser: boolean;
  dependencies: any[];
  category: string;
  resolvedDependencies: any[];
  platform: any[];
  package: {
    name: string;
    namespace: string;
  };
}

async function awsHandler(event: SNSEvent): Promise<void> {
  const promises = event.Records.map((record) => resolveToDocuments(record));
  const documents = await Promise.all(promises);

  return await invokeService("search", "indexing", {
    indexName: "packages",
    type: "release",
    data: documents,
  });
}

async function resolveToDocuments(record: SNSEventRecord) {
  const {
    readme,
    package: { name, namespace },
    platform,
    resolvedDependencies,
    superuser,
    version,
    description,
    category,
  }: IMessage = JSON.parse(record.Sns.Message);
  const readmeContent = await getAssetContent(readme);

  const target = `${namespace || "none"}/${name}`;
  const packageHash = md5((namespace || "none") + name);
  const documentId = md5([namespace, name, version].join("::"));

  const document = {
    id: documentId,
    readme: readmeContent,
    name,
    namespace,
    target,
    packageHash,
    versionNum: semver2int(version),
    category,
    version,
    description,
    superuser,
    platform,
    dependencies: resolvedDependencies,
  };

  return document;
}

async function getAssetContent(asset: { id: string }) {
  const { content } = await invokeService("assets", "get", asset);
  const buff = new Buffer(content, "base64");
  return buff.toString("utf-8");
}

export const handler = initCommonMiddlewares(awsHandler);
