'use strict';

const semver = require('semver');

const { execDocker, getLatestStrapiRelease } = require('./utils');
const { STRAPI_IMAGE_NAME, NODE_VERSIONS, LATEST_NODE_VERSION } = require('./constants');

module.exports = {
  buildStrapiImages,
};

async function buildStrapiImages({ version, shouldPush = false } = {}) {
  if (version === 'latest' || !version) {
    version = await getLatestStrapiRelease();
  }

  if (semver.valid(version) === null) {
    throw new Error('Invalid strapi version provided: ' + version);
  }

  const createdTags = [];

  for (const nodeVersion of NODE_VERSIONS) {
    const tags = await buildStrapiImage({ nodeVersion, version, shouldPush });

    createdTags.push(...tags);
  }

  return createdTags.map(tag => `${STRAPI_IMAGE_NAME}:${tag}`);
}

async function buildStrapiImage({ nodeVersion, version, shouldPush = false }) {
  let tmpImg = `${STRAPI_IMAGE_NAME}:tmp`;

  await execDocker([
    'build',
    '--build-arg',
    `BASE_VERSION=${nodeVersion}`,
    '--build-arg',
    `STRAPI_VERSION=${version}`,
    '-t',
    tmpImg,
    './strapi',
  ]);

  const tags = buildStrapiTags({ version, nodeVersion });

  for (let tag of tags) {
    await execDocker(['tag', tmpImg, `${STRAPI_IMAGE_NAME}:${tag}`]);

    if (shouldPush) {
      await execDocker(['push', `${STRAPI_IMAGE_NAME}:${tag}`]);
    }
  }

  await execDocker(['image', 'rm', tmpImg]);

  return tags;
}

function buildStrapiTags({ version: strapiVersion, nodeVersion}) {
  let tags = [];
  let versions = [strapiVersion];

  const major = semver.major(strapiVersion);
  const minor = semver.minor(strapiVersion);
  const patch = semver.patch(strapiVersion);
  const pre = semver.prerelease(strapiVersion);

  if (!pre) {
    versions = [major, `${major}.${minor}`, `${major}.${minor}.${patch}`];
  }

  for (const version of versions) {
    tags.push(`${version}-node${nodeVersion}`);

    if (nodeVersion === LATEST_NODE_VERSION) {
      tags.push(`${version}`);
    }
  }

  if (nodeVersion === LATEST_NODE_VERSION) {
    tags.push('latest');
  }

  return tags;
}
