/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.
 */

/* eslint-disable-next-line no-unused-vars */
const { dest, series, parallel, src, symlink } = require('gulp')
const del = require('del')
const filter = require('gulp-filter')
const inject = require('gulp-inject')
const map = require('map-stream')
const path = require('path')
const rename = require('gulp-rename')
const replace = require('gulp-replace')
const sort = require('gulp-sort')
const through2 = require('through2')
const File = require('vinyl')
const fs = require('fs')

function deleteComponentSymlinks () {
  return del([
    'components/modules/ROOT/pages/*',
    '!components/modules/ROOT/pages/index.adoc',
  ])
}

function deleteComponentImageSymlinks () {
  return del(['components/modules/ROOT/assets/images/*'])
}

function createComponentSymlinks () {
  return (
    src([
      '../core/camel-base/src/main/docs/*-component.adoc',
      '../components/{*,*/*}/src/main/docs/*-component.adoc',
      '../components/{*,*/*}/src/main/docs/*-summary.adoc',
    ])
      .pipe(
        map((file, done) => {
          // this flattens the output to just .../pages/....adoc
          // instead of .../pages/camel-.../src/main/docs/....adoc
          file.base = path.dirname(file.path)
          done(null, file)
        })
      )
      // Antora disabled symlinks, there is an issue open
      // https://gitlab.com/antora/antora/issues/188
      // to reinstate symlink support, until that's resolved
      // we'll simply copy over instead of creating symlinks
      // .pipe(symlink('components/modules/ROOT/pages/', {
      //     relativeSymlinks: true
      // }));
      // uncomment above .pipe() and remove the .pipe() below
      // when antora#188 is resolved
      .pipe(insertSourceAttribute())
      .pipe(dest('components/modules/ROOT/pages/'))
  )
}

function createComponentOthersSymlinks () {
  const f = filter([
    '**',
    '!**/*-language.adoc',
    '!**/*-dataformat.adoc',
    '!**/*-component.adoc',
    '!**/*-summary.adoc',
  ])
  return (
    src([
      '../core/camel-base/src/main/docs/*.adoc',
      '../core/camel-main/src/main/docs/*.adoc',
      '../components/{*,*/*}/src/main/docs/*.adoc',
    ])
      .pipe(f)
      .pipe(
        map((file, done) => {
          // this flattens the output to just .../pages/....adoc
          // instead of .../pages/camel-.../src/main/docs/....adoc
          file.base = path.dirname(file.path)
          done(null, file)
        })
      )
      // Antora disabled symlinks, there is an issue open
      // https://gitlab.com/antora/antora/issues/188
      // to reinstate symlink support, until that's resolved
      // we'll simply copy over instead of creating symlinks
      // .pipe(symlink('components/modules/ROOT/pages/', {
      //     relativeSymlinks: true
      // }));
      // uncomment above .pipe() and remove the .pipe() below
      // when antora#188 is resolved
      .pipe(insertSourceAttribute())
      .pipe(dest('components/modules/others/pages/'))
  )
}

function createComponentDataFormatSymlinks () {
  return (
    src(['../components/{*,*/*}/src/main/docs/*-dataformat.adoc'])
      .pipe(
        map((file, done) => {
          // this flattens the output to just .../pages/....adoc
          // instead of .../pages/camel-.../src/main/docs/....adoc
          file.base = path.dirname(file.path)
          done(null, file)
        })
      )
      // Antora disabled symlinks, there is an issue open
      // https://gitlab.com/antora/antora/issues/188
      // to reinstate symlink support, until that's resolved
      // we'll simply copy over instead of creating symlinks
      // .pipe(symlink('components/modules/ROOT/pages/', {
      //     relativeSymlinks: true
      // }));
      // uncomment above .pipe() and remove the .pipe() below
      // when antora#188 is resolved
      .pipe(insertSourceAttribute())
      .pipe(dest('components/modules/dataformats/pages/'))
  )
}

function createComponentLanguageSymlinks () {
  return (
    src(['../components/{*,*/*}/src/main/docs/*-language.adoc'])
      .pipe(
        map((file, done) => {
          // this flattens the output to just .../pages/....adoc
          // instead of .../pages/camel-.../src/main/docs/....adoc
          file.base = path.dirname(file.path)
          done(null, file)
        })
      )
      // Antora disabled symlinks, there is an issue open
      // https://gitlab.com/antora/antora/issues/188
      // to reinstate symlink support, until that's resolved
      // we'll simply copy over instead of creating symlinks
      // .pipe(symlink('components/modules/ROOT/pages/', {
      //     relativeSymlinks: true
      // }));
      // uncomment above .pipe() and remove the .pipe() below
      // when antora#188 is resolved
      .pipe(insertSourceAttribute())
      .pipe(dest('components/modules/languages/pages/'))
  )
}

function createComponentImageSymlinks () {
  return (
    src('../components/{*,*/*}/src/main/docs/*.png')
      .pipe(
        map((file, done) => {
          // this flattens the output to just .../pages/....adoc
          // instead of .../pages/camel-.../src/main/docs/....adoc
          file.base = path.dirname(file.path)
          done(null, file)
        })
      )
      // Antora disabled symlinks, there is an issue open
      // https://gitlab.com/antora/antora/issues/188
      // to reinstate symlink support, until that's resolved
      // we'll simply copy over instead of creating symlinks
      // .pipe(symlink('components/modules/ROOT/pages/', {
      //     relativeSymlinks: true
      // }));
      // uncomment above .pipe() and remove the .pipe() below
      // when antora#188 is resolved
      .pipe(dest('components/modules/ROOT/assets/images/'))
  )
}

function titleFrom (file) {
  var maybeName = /(?::docTitle: )(.*)/.exec(file.contents.toString())
  if (maybeName === null) {
    //TODO investigate these... why dont they have them?
    // console.warn(`${file.path} doesn't contain Asciidoc docTitle attribute (':docTitle: <Title>'`);
    maybeName = /(?:=|#) (.*)/.exec(file.contents.toString())
    if (maybeName === null) {
      throw new Error(
        `${file.path} also doesn't contain Asciidoc heading ('= <Title>') or ('# <Title')`
      )
    }
  }

  return maybeName[1]
}

function groupFrom (file) {
  var groupName = /(?::group: )(.*)/.exec(file.contents.toString())
  if (groupName !== null) return groupName[1]
  return null
}

function compare (file1, file2) {
  if (file1 === file2) return 0
  return titleFrom(file1).toUpperCase() < titleFrom(file2).toUpperCase()
    ? -1
    : 1
}

function compareComponents (file1, file2) {
  if (file1 === file2) return 0
  const group1 = groupFrom(file1) ? groupFrom(file1).toUpperCase() : null
  const group2 = groupFrom(file2) ? groupFrom(file2).toUpperCase() : null
  const title1 = titleFrom(file1).toUpperCase()
  const title2 = titleFrom(file2).toUpperCase()

  if (group1 === null && group2 === null) return title1 < title2 ? -1 : 1
  if (group2 !== null && group1 === null) {
    if (title1 === group2) return -1
    return title1 < group2 ? -1 : 1
  }
  if (group1 !== null && group2 === null) {
    if (title2 === group1) return 1
    return group1 < title2 ? -1 : 1
  }
  if (group1 !== null && group2 !== null) {
    if (group1 === group2) return title1 < title2 ? -1 : 1
    return group1 < group2 ? -1 : 1
  }
}

function insertGeneratedNotice () {
  return inject(src('./generated.txt'), {
    name: 'generated',
    removeTags: true,
    transform: (filename, file) => {
      return file.contents.toString('utf8')
    },
  })
}

function insertSourceAttribute () {
  return replace(/^= .+/m, function (match) {
    return `${match}\n//THIS FILE IS COPIED: EDIT THE SOURCE FILE:\n:page-source: ${path.relative('..', this.file.path)}`
  })
}

function createComponentNav () {
  return src('component-nav.adoc.template')
    .pipe(insertGeneratedNotice())
    .pipe(
      inject(
        src([
          'components/modules/ROOT/pages/**/*.adoc',
          '!components/modules/ROOT/pages/index.adoc',
        ]).pipe(sort(compareComponents)),
        {
          removeTags: true,
          transform: (filename, file) => {
            const filepath = path.basename(filename)
            const title = titleFrom(file)
            if (groupFrom(file) !== null) { return `*** xref:${filepath}[${title}]` }
            return `** xref:${filepath}[${title}]`
          },
        }
      )
    )
    .pipe(rename('nav.adoc'))
    .pipe(dest('components/modules/ROOT/'))
}

function createComponentOthersNav () {
  return src('component-others-nav.adoc.template')
    .pipe(insertGeneratedNotice())
    .pipe(
      inject(
        src([
          'components/modules/others/pages/**/*.adoc',
          '!components/modules/others/pages/index.adoc',
        ]).pipe(sort(compare)),
        {
          removeTags: true,
          transform: (filename, file) => {
            const filepath = path.basename(filename)
            const title = titleFrom(file)
            return `** xref:${filepath}[${title}]`
          },
        }
      )
    )
    .pipe(rename('nav.adoc'))
    .pipe(dest('components/modules/others/'))
}

function createComponentDataFormatsNav () {
  return src('component-dataformats-nav.adoc.template')
    .pipe(insertGeneratedNotice())
    .pipe(
      inject(
        src([
          'components/modules/dataformats/pages/**/*.adoc',
          '!components/modules/dataformats/pages/index.adoc',
        ]).pipe(sort(compare)),
        {
          removeTags: true,
          transform: (filename, file) => {
            const filepath = path.basename(filename)
            const title = titleFrom(file)
            return `** xref:dataformats:${filepath}[${title}]`
          },
        }
      )
    )
    .pipe(rename('nav.adoc'))
    .pipe(dest('components/modules/dataformats/'))
}

function createComponentLanguagesNav () {
  return src('component-languages-nav.adoc.template')
    .pipe(insertGeneratedNotice())
    .pipe(
      inject(
        src([
          'components/modules/languages/pages/**/*.adoc',
          '../core/camel-core-languages/src/main/docs/modules/languages/pages/*.adoc',
          '../core/camel-xml-jaxp/src/main/docs/modules/languages/pages/*.adoc',
          '!components/modules/languages/pages/index.adoc',
        ]).pipe(sort(compare)),
        {
          removeTags: true,
          transform: (filename, file) => {
            const filepath = path.basename(filename)
            const title = titleFrom(file)
            return `** xref:languages:${filepath}[${title}]`
          },
        }
      )
    )
    .pipe(rename('nav.adoc'))
    .pipe(dest('components/modules/languages/'))
}

function createEIPNav () {
  const f = filter(['**', '!**/enterprise-integration-patterns.adoc'])
  return src('eip-nav.adoc.template')
    .pipe(insertGeneratedNotice())
    .pipe(
      inject(
        src('../core/camel-core-engine/src/main/docs/modules/eips/pages/*.adoc')
          .pipe(f)
          .pipe(sort(compare)),
        {
          removeTags: true,
          name: 'eips',
          transform: (filename, file) => {
            const filepath = path.basename(filename)
            const title = titleFrom(file)
            return ` ** xref:eips:${filepath}[${title}]`
          },
        }
      )
    )
    .pipe(rename('nav.adoc'))
    .pipe(dest('../core/camel-core-engine/src/main/docs/modules/eips/'))
}

const extractExamples = function (file, enc, next) {
  const asciidoc = file.contents.toString()
  const includes = /(?:include::\{examplesdir\}\/)([^[]+)/g
  let example
  const exampleFiles = new Set()
  while ((example = includes.exec(asciidoc))) {
    const examplePath = path.resolve(path.join('..', example[1]))
    exampleFiles.add(examplePath)
  }
  // (exampleFiles.size > 0) && console.log('example files', exampleFiles)
  exampleFiles.forEach((examplePath) =>
    this.push(
      new File({
        base: path.resolve('..'),
        path: examplePath,
        contents: fs.createReadStream(examplePath),
      })
    )
  )

  return next()
}

function deleteExamples () {
  return del([
    'user-manual/modules/ROOT/examples/',
    'user-manual/modules/faq/examples/',
    'components/modules/ROOT/examples/',
  ])
}

function createUserManualExamples () {
  return src('user-manual/modules/ROOT/**/*.adoc')
    .pipe(through2.obj(extractExamples))
    .pipe(dest('user-manual/modules/ROOT/examples/'))
}

function createFAQExamples () {
  return src('user-manual/modules/faq/**/*.adoc')
    .pipe(through2.obj(extractExamples))
    .pipe(dest('user-manual/modules/faq/examples/'))
}

function createEIPExamples () {
  return src('../core/camel-core-engine/src/main/docs/modules/eips/**/*.adoc')
    .pipe(through2.obj(extractExamples))
    .pipe(
      dest('../core/camel-core-engine/src/main/docs/modules/eips/examples/')
    )
}

function createUserManualLanguageExamples () {
  return src(
    '../core/camel-core-languages/src/main/docs/user-manual/modules/languages/**/*.adoc'
  )
    .pipe(through2.obj(extractExamples))
    .pipe(dest('user-manual/modules/ROOT/examples/'))
}

function createComponentExamples () {
  return src('../components/{*,*/*}/src/main/docs/*.adoc')
    .pipe(through2.obj(extractExamples))
    .pipe(dest('components/modules/ROOT/examples/'))
}

const symlinks = parallel(
  series(
    deleteComponentSymlinks,
    createComponentSymlinks,
    createComponentOthersSymlinks,
    createComponentDataFormatSymlinks,
    createComponentLanguageSymlinks
  ),
  series(deleteComponentImageSymlinks, createComponentImageSymlinks)
)
const nav = parallel(
  createComponentNav,
  createComponentOthersNav,
  createComponentDataFormatsNav,
  createComponentLanguagesNav,
  createEIPNav
)
const examples = series(
  deleteExamples,
  createUserManualExamples,
  createFAQExamples,
  createEIPExamples,
  createUserManualLanguageExamples,
  createComponentExamples
)

exports.symlinks = symlinks
exports.nav = nav
exports.examples = examples
exports.default = series(symlinks, nav, examples)
