/*
 * Licensed to Elasticsearch B.V. under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch B.V. 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 { join } = require('path')
const { writeFile } = require('fs/promises')
const fetch = require('node-fetch')
const rimraf = require('rimraf')
const ora = require('ora')
const { convertRequests } = require('@elastic/request-converter')
const minimist = require('minimist')

const docsExamplesDir = join(__dirname, '../../docs', 'examples')

const log = ora('Generating example snippets')

const failures = {}

async function getAlternativesReport (version = 'master') {
  const reportUrl = `https://raw.githubusercontent.com/elastic/built-docs/master/raw/en/elasticsearch/reference/${version}/alternatives_report.json`
  const response = await fetch(reportUrl)
  if (!response.ok) {
    log.fail(`unexpected response ${response.statusText}`)
    process.exit(1)
  }
  return await response.json()
}

async function makeSnippet (example) {
  const { source, digest } = example
  const fileName = `${digest}.asciidoc`
  const filePath = join(docsExamplesDir, fileName)

  try {
    const code = await convertRequests(source, 'python', {
      complete: false,
      printResponse: true
    })
    await writeFile(filePath, asciidocWrapper(code, example), 'utf8')
  } catch (err) {
    failures[digest] = err.message
  }
}

async function generate (version) {
  log.start()

  rimraf.sync(join(docsExamplesDir, '*'))

  log.text = `Downloading alternatives report for version ${version}`
  const examples = await getAlternativesReport(version)

  let counter = 1
  for (const example of examples) {
    log.text = `${counter++}/${examples.length}: ${example.digest}`

    // skip over bad request definitions
    if (example.source.startsWith('{') || example.source.endsWith('...')) {
      failures[example.digest] = 'Incomplete request syntax'
      continue
    }

    await makeSnippet(example)
  }
}

function asciidocWrapper (source, example) {
  return `// This file is autogenerated, DO NOT EDIT
// ${example.source_location.file}:${example.source_location.line}

[source, python]
----
${source.trim()}
----
`
}

const options = minimist(process.argv.slice(2), {
  string: ['version'],
  default: {
    version: 'master'
  }
})

generate(options.version)
  .then(() => log.succeed('done!'))
  .catch(err => log.fail(err.message))
  .finally(() => {
    const keys = Object.keys(failures)
    if (keys.length > 0) {
      let message = 'Some examples failed to generate:\n\n'
      for (const key of keys) {
        message += `${key}: ${failures[key]}\n`
      }
      console.error(message)
    }
  })
