/*
 * 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.
 */
const { dest, series, parallel, src, symlink } = require('gulp');
const del = require('del');
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/*.adoc', '../components/{*,*/*}/src/main/docs/*.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 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 deleteUserManualSymlinks() {
    return del(['user-manual/modules/ROOT/pages/*-eip.adoc', 'user-manual/modules/ROOT/pages/*-language.adoc']);
}

function createUserManualSymlinks() {
    return src(['../core/camel-base/src/main/docs/*.adoc', '../core/camel-core-engine/src/main/docs/eips/*.adoc'])
        // 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('user-manual/modules/ROOT/pages/', {
        //     relativeSymlinks: true
        // }));
        // uncomment above .pipe() and remove the .pipe() below
        // when antora#188 is resolved
        .pipe(insertSourceAttribute())
        .pipe(dest('user-manual/modules/ROOT/pages/'));
}

function titleFrom(file) {
    const maybeName = /(?:=|#) (.*)/.exec(file.contents.toString())
    if (maybeName == null) {
        throw new Error(`${file.path} doesn't contain Asciidoc heading ('= <Title>') or ('# <Title')`);
    }

    return maybeName[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:page-source: ${path.relative('..', this.file.path)}`;
    });
}

function createUserManualNav() {
    return src('user-manual-nav.adoc.template')
        .pipe(insertGeneratedNotice())
        .pipe(inject(src('../core/camel-base/src/main/docs/*.adoc').pipe(sort()), {
            removeTags: true,
            name: 'languages',
            transform: (filename, file) => {
                const filepath = path.basename(filename);
                const title = titleFrom(file);
                return ` ** xref:${filepath}[${title}]`;
            }
        }))
        .pipe(inject(src('../core/camel-core-engine/src/main/docs/eips/*.adoc').pipe(sort()), {
            removeTags: true,
            name: 'eips',
            transform: (filename, file) => {
                const filepath = path.basename(filename);
                const title = titleFrom(file);
                return ` ** xref:${filepath}[${title}]`;
            }
        }))
        .pipe(rename('nav.adoc'))
        .pipe(dest('user-manual/modules/ROOT/'))
}

const extractExamples = function(file, enc, next) {
    const asciidoc = file.contents.toString();
    const includes = /(?:include::\{examplesdir\}\/)([^[]+)/g;
    let example;
    let exampleFiles = new Set()
    while (example = includes.exec(asciidoc)) {
        let examplePath = path.resolve(path.join('..', example[1]));
        exampleFiles.add(examplePath);
    }

    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/', '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 createComponentExamples() {
    return src('../components/{*,*/*}/src/main/docs/*.adoc')
        .pipe(through2.obj(extractExamples))
        .pipe(dest('components/modules/ROOT/examples/'));
}

const symlinks = parallel(
  series(deleteComponentSymlinks, createComponentSymlinks),
  series(deleteComponentImageSymlinks, createComponentImageSymlinks),
  series(deleteUserManualSymlinks, createUserManualSymlinks)
);
const nav = parallel(createUserManualNav);
const examples = series(deleteExamples, createUserManualExamples, createComponentExamples);

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

