import * as md5 from "md5";
import {
  DESCRIPTION_MAX_LENGTH,
  NAME_MAX_LENGTH,
  NAME_MIN_LENGTH,
  TOKEN_MAX_LENGTH,
} from "./base";
import { LambdaInvoker } from "./LambdaInvoker";
import { IActivity, WorkflowInvoker } from "./WorkflowInvoker";

const getPackage = new LambdaInvoker("package", "get", {
  properties: {
    name: { type: "string", format: "name" },
  },
  required: ["name"],
  type: "object",
});

const getUserPackages = new LambdaInvoker("package", "getFromUser", {
  properties: {
    user: {
      type: "object",
      properties: {
        username: {
          type: "string",
        },
      },
      required: ["username"],
    },
  },
  required: ["user"],
  type: "object",
});

/**
 * Special publish workflow invoker to define activity.
 */
class PublishWorkflowInvoker extends WorkflowInvoker {
  public getActivity({ name, namespace, version }): IActivity {
    // same implementation as the script: packageHash
    const packageHash = md5((namespace || "none") + name);

    return {
      id: packageHash,
      type: "publish",
      value: version,
    };
  }
}

const publish = new PublishWorkflowInvoker("publish", {
  properties: {
    description: { type: "string", maxLength: DESCRIPTION_MAX_LENGTH },
    name: {
      type: "string",
      format: "name",
      maxLength: NAME_MAX_LENGTH,
      minLength: NAME_MIN_LENGTH,
    },
    namespace: {
      type: "string",
      format: "name",
      maxLength: NAME_MAX_LENGTH,
      minLength: NAME_MIN_LENGTH,
    },
    version: { type: "string", format: "semver" },
    execute: {
      type: "object",
      properties: { id: { type: "string" } },
      required: ["id"],
    },
    readme: {
      type: "object",
      properties: { id: { type: "string" } },
      required: ["id"],
    },
    superuser: { type: "boolean" },
    accessToken: {
      maxLength: TOKEN_MAX_LENGTH,
      type: "string",
    },
    dependencies: {
      type: "array",
      items: {
        type: "object",
        properties: {
          name: {
            type: "string",
            format: "target",
            maxLength: NAME_MAX_LENGTH * 2 + 1,
            minLength: NAME_MIN_LENGTH,
          },
          version: {
            type: "string",
            format: "semver",
          },
        },
        required: ["name", "version"],
      },
      maxItems: 10,
    },
    platform: {
      type: "array",
      items: {
        type: "object",
        properties: {
          os: { type: "string" },
          dist: { type: "string" },
          codename: { type: "string" },
        },
        required: ["os", "dist", "codename"],
      },
      maxItems: 10,
    },
    category: {
      type: "string",
      maxLength: 50,
    },
  },
  required: [
    "name",
    "version",
    "execute",
    "accessToken",
    "description",
    "readme",
    "category",
  ],
  type: "object",
});

export { getPackage, publish, getUserPackages };
