#!/usr/bin/env ts-node

import * as Path from 'path'
import * as Fs from 'fs'

import Ajv, { ErrorObject } from 'ajv'

function handleError(error: string) {
  console.error(error)
  process.exit(-1)
}

function formatErrors(errors: ErrorObject[]): string {
  return errors
    .map(error => {
      const { dataPath, message } = error
      const additionalProperties = error.params as any
      const additionalProperty = additionalProperties.additionalProperty as string

      let additionalPropertyText = ''

      if (additionalProperty != null) {
        additionalPropertyText = `, found: '${additionalProperties.additionalProperty}'`
      }

      // dataPath starts with a leading "."," which is a bit confusing
      const element = dataPath.substring(1)

      return ` - ${element} - ${message}${additionalPropertyText}`
    })
    .join('\n')
}

const repositoryRoot = Path.dirname(__dirname)
const changelogPath = Path.join(repositoryRoot, 'changelog.json')

// eslint-disable-next-line no-sync
const changelog = Fs.readFileSync(changelogPath, 'utf8')

let changelogObj = null

try {
  changelogObj = JSON.parse(changelog)
} catch {
  handleError(
    'Unable to parse the contents of changelog.json into a JSON object. Please review the file contents.'
  )
}

const schema = {
  $schema: 'http://json-schema.org/draft-07/schema#',
  type: 'object',
  properties: {
    releases: {
      type: 'object',
      patternProperties: {
        '^([0-9]+.[0-9]+.[0-9]+)(-beta[0-9]+|-test[0-9]+)?$': {
          type: 'array',
          items: {
            type: 'string',
          },
          uniqueItems: true,
        },
      },
      additionalProperties: false,
    },
  },
}

const ajv = new Ajv({ allErrors: true, uniqueItems: true })
const validate = ajv.compile(schema)

const valid = validate(changelogObj)

if (!valid && validate.errors != null) {
  handleError(`Errors: \n${formatErrors(validate.errors)}`)
}

console.log('The changelog is totally fine')
