/**
 * Licensed 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.
 */
package org.apache.winegrower.build

import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest
import org.apache.maven.settings.crypto.SettingsDecrypter
import org.asciidoctor.Asciidoctor
import org.asciidoctor.AttributesBuilder
import org.asciidoctor.OptionsBuilder
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider

import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.SimpleFileVisitor
import java.nio.file.StandardCopyOption
import java.nio.file.attribute.BasicFileAttributes

import static java.util.Collections.singleton

def color = '#303284'
def inlineCss = """
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
main {
  background-color: white !important;
}
*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; 
  height: 75px; 
  visibility: hidden; 
}
#header {
  background-color: white;
}
.row {
  margin: 0 !important;
}
"""
def header = """
  <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark" style="background-color: ${color} !important;">
    <div class="container">
      <a class="navbar-brand" href="index.html">
        <img src="https://karaf.apache.org/images/karaf-logo-new.png">
      </a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse justify-content-end" id="navbarCollapse">
        <div>
          <ul class="navbar-nav mr-auto align-items-center text-uppercase">
            <li class="nav-item active">
              <a class="nav-link" href="index.html">Home</span></a>
            </li>
            <!--
            <li class="nav-item">
              <a class="nav-link" href="download.html">Download</a>
            </li>
            -->
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                Documentation
              </a>
              <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                <a class="dropdown-item" href="@{relativePath}index.html">Home</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="@{relativePath}getting-started.html">Getting Started</a>
                <a class="dropdown-item" href="@{relativePath}core/index.html">Core</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="@{relativePath}extension/index.html">Extensions</a>
                <a class="dropdown-item" href="@{relativePath}extension/maven/index.html">Maven</a>
                <a class="dropdown-item" href="@{relativePath}extension/junit5/index.html">Junit 5</a>
                <a class="dropdown-item" href="@{relativePath}extension/cdi/index.html">CDI</a>
                <a class="dropdown-item" href="@{relativePath}extension/servlet/index.html">Servlet</a>
                <a class="dropdown-item" href="@{relativePath}extension/agent/index.html">Javaagent</a>
              </div>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="https://karaf.apache.org/community.html">Community</a>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" href="https://www.apache.org">
                <img src="https://karaf.apache.org/images/apache-feather-tm-new.png">
              </a>
            </li>
          </ul>
        <div>
      </div>
    </div>
  </div></div></nav>
"""

def footer= """
<footer class="container-fluid bg-dark text-white text-center" style="background-color: ${color} !important;">
  <div class="mx-auto">
    <blockquote class="blockquote"><p class="mb-0 text-white">Karaf goodness without OSGi build headache!</div></blockquote>
  </div>
  <p class="float-right"><a href="#">Back to top</a></p>
  <p>&copy; 2018 <a href="https://www.apache.org">Apache Software Foundation</a> - <a href="privacy.html">Privacy Policy</a><br>
  Apache Karaf, Karaf, Apache, the Apache feather logo, and the Apache Karaf project logo are trademarks of The Apache Software Foundation.</p>
</footer>
"""

def bootstrapCss = """
<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\" integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\" crossorigin=\"anonymous\">
"""
def bootstrapJs = """
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
"""
def otherJs = """
<script>
(function () {
  var anchors = document.querySelectorAll('h2');
  var wrapper = document.querySelector('div.anchors');
  if (!anchors || anchors.length == 0) {
    document.querySelector('main > div').className = 'col-sm-12';
    wrapper.className = '';
    return;
  }
  var ul = document.createElement('ul');
  var title = document.createElement('h2');
  title.innerHTML = 'Menu';
  ul.append(title);
  wrapper.append(ul);
  function addLink(elt) {
    var name = elt.innerHTML;
    var id = elt.id;
    if (!id) {
      return;
    }
    var link = document.createElement('a');
    link.href = '#' + id;
    link.innerHTML = name;
    var li = document.createElement('li');
    li.append(link);
    ul.append(li);
  }
  anchors.forEach(addLink);
})();
</script>
"""

def root = project.basedir.parentFile
def output = new File(project.build.directory, 'documentation')
def adoc = Asciidoctor.Factory.create()
// copy css
def cssSource = new File(project.basedir, '.asciidoctor/theme/manual/src/main/asciidoc/style/apache.css')
def copyCss = { ref ->
    def apacheCss = new File(ref.parentFile, 'css/apache.css')
    if (apacheCss.exists()) {
        return
    }
    apacheCss.parentFile.mkdirs()
    apacheCss.text = cssSource.text

    stream = Thread.currentThread().getContextClassLoader()
            .getResourceAsStream("gems/asciidoctor-1.5.7.1/data/stylesheets/coderay-asciidoctor.css")
    Files.copy(stream, new File(apacheCss.parentFile, 'coderay-asciidoctor.css').toPath(), StandardCopyOption.REPLACE_EXISTING)
    stream.close()
}


def render = {file ->
    def module = file.parentFile.parentFile.parentFile.parentFile
    def relativePath = root.toPath().relativize(file.parentFile.toPath()).toString()
    def sanitizedpath = relativePath
            .replace('winegrower-', '')
            .replace('testing-', '')
            .replace('-plugin', '')
            .replace('/build', '')
            .replace('/testing', '')
            .replace(File.separator, '/')
            .replace('/src/main/asciidoc', '') + '/'
    def htmlName = file.name.substring(0, file.name.length() - 'adoc'.length()) + 'html'
    def fileName = (module.name == 'winegrower-documentation' ? '' : sanitizedpath) + htmlName
    log.info("Rendering ${file} to ${output}/${fileName}")
    def attributes = AttributesBuilder.attributes()
            .docType('article')
            .imagesDir("${project.basedir}/.asciidoctor/theme/manual/src/main/theme/images")
            .icons('font')
            .dataUri(true)
            .setAnchors(true)
            .stylesDir('css')
            .styleSheetName('apache.css')
            .attribute('source-highlighter', 'coderay')
            .attribute('idprefix')
            .attribute('idseparator', '-')
            .attribute('source-highlighter', 'coderay')
            .get()
    def options = OptionsBuilder.options()
            .backend('html5')
            .headerFooter(true)
            .inPlace(false)
            .baseDir(new File("${project.build.directory}"))
            .attributes(attributes)

    def rendered = adoc.render(file.text, options)
    def renderedFile = new File(output, fileName)
    renderedFile.parentFile.mkdirs()
    def relativeLink = renderedFile.parentFile.toPath().relativize(output.toPath()).toString()
    if (!relativeLink.isEmpty()) {
        relativeLink = relativeLink + '/'
    }
    renderedFile.text = rendered
            // wrap in main tag
            .replace('<div id="header">', "${header.replace('@{relativePath}', relativeLink)}" +
                "<main class=\"row\" role=\"main\"><div class=\"col-sm-10\">" +
                "<div id=\"header\" class=\"container\">")
            .replace('<div id="content"', '<div id="content" class="container"')
            .replace('</body>', "</div><div class=\"anchors col-sm-2\"></div></main>${footer}</body>")
            .replace('<body', "<body style=\"padding-top: 3rem;background-color: ${color} !important;\"")
            // add bootstrap and move apache css at the end to ensure it is used
            .replace('<link rel="stylesheet" href="css/apache.css">', '')
            .replace('</head>', "${bootstrapCss}<link rel=\"stylesheet\" href=\"css/apache.css\"><style>${inlineCss}</style></head>")
            .replace('</body>', "</div>${bootstrapJs}${otherJs}</body>")
            // home link
            .replace('"index.html"', "\"${relativeLink}index.html\"")
            // drop adoc footer
            .replaceAll('<div id="footer-text">[^<]+</div>', '')
            .replaceAll('<div id="footer">[^<]+</div>', '')

    copyCss(renderedFile)
}

// only support flat .adoc in src/main/asciidoc for now
Files.walkFileTree(root.toPath(), new SimpleFileVisitor<Path>() {
    @Override
    FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        def asFile = dir.toFile()
        if (new File(asFile, 'pom.xml').exists()
                || new File(asFile, 'main').exists()
                || new File(asFile, 'asciidoc').exists()
                || 'asciidoc' == asFile.name) {
            return FileVisitResult.CONTINUE
        }
        return FileVisitResult.SKIP_SUBTREE
    }

    @Override
    FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        def asFile = file.toFile()
        if (asFile.name.endsWith(".adoc") && 'README.adoc' != asFile.name) {
            render(asFile)
        }
        return FileVisitResult.CONTINUE
    }
})



if (project.properties["winegrower.documentation.publish"] == 'true') {

    def source = new File(project.build.directory, 'documentation')
    if (!source.exists() || !new File(source, 'index.html').exists()) {
        log.warn('Not ready to deploy, skipping')
        return
    }

    def branch = 'refs/heads/gh-pages'
    def workDir = new File(project.build.directory, UUID.randomUUID().toString() + '_' + System.currentTimeMillis())

    def url = project.parent.scm.url
    def serverId = project.properties['github.serverId']
    log.info("Using server ${serverId}")

    def server = session.settings.servers.findAll { it.id == serverId }.iterator().next()
    def decryptedServer = session.container.lookup(SettingsDecrypter).decrypt(new DefaultSettingsDecryptionRequest(server))
    server = decryptedServer.server != null ? decryptedServer.server : server

    log.info("Using url=${url}")
    log.info("Using user=${server.username}")
    log.info("Using branch=${branch}")

    def credentialsProvider = new UsernamePasswordCredentialsProvider(server.username, server.password)
    def git = Git.cloneRepository()
            .setCredentialsProvider(credentialsProvider)
            .setURI(url)
            .setDirectory(workDir)
            .setBranchesToClone(singleton(branch))
            .setBranch(branch)
            .call()

    new AntBuilder().copy(todir: workDir.absolutePath, overwrite: true) {
        fileset(dir: source.absolutePath)
    }

    // we don't drop old files, stay conservative for now
    def message = "Updating the documentation for version ${project.version} // " + new Date().toString()
    git.add().addFilepattern(".").call()
    git.commit().setAll(true).setMessage(message).call()
    git.status().call()
    git.push().setCredentialsProvider(credentialsProvider).add(branch).call()
    log.info("Updated the documentation on ${new Date()}")
}