################################################################################
#                  MakieGallery.jl documentation build script                  #
################################################################################
##############################
#      Generic imports       #
##############################

using Documenter, Markdown, Pkg, Random, FileIO


##############################
#      Specific imports      #
##############################

using MakieGallery, AbstractPlotting
AbstractPlotting.inline!(true)

makiegallerydir = dirname(dirname(pathof(Base.moduleroot(MakieGallery))))

import AbstractPlotting: to_string

using MakieGallery: print_table


################################################################################
#                              Utility functions                               #
################################################################################


################################################################################
#                                    Setup                                     #
################################################################################

database = MakieGallery.load_database()

pathroot  = normpath(@__DIR__, "..")
docspath  = joinpath(pathroot, "docs")
srcpath   = joinpath(docspath, "src")
srcgenpath   = joinpath(docspath, "src_generation")
buildpath = joinpath(docspath, "build")
genpath   = joinpath(srcpath, "generated")

mkpath(genpath)

################################################################################
#                          Syntax highlighting theme                           #
################################################################################

@info("Writing highlighting stylesheet")
open(joinpath(srcpath, "assets", "syntaxtheme.css"), "w") do io
    MakieGallery.Highlights.stylesheet(io, MIME("text/css"), MakieGallery.DEFAULT_HIGHLIGHTER[])
end

################################################################################
#                      Automatic Markdown page generation                      #
################################################################################


########################################
#       Plot attributes overview       #
########################################

# automatically generate an overview of the plot attributes (keyword arguments), using a source md file
@info("Generating attributes page")
include(joinpath(makiegallerydir, "src/plot_attr_desc.jl"))
path = joinpath(genpath, "plot-attributes.md")
srcdocpath = joinpath(srcgenpath, "src-plot-attributes.md")
open(path, "w") do io
    !ispath(srcdocpath) && error("source document doesn't exist!")
    println(io, "# Plot attributes")
    src = read(srcdocpath, String)
    println(io, src)
    print(io, "\n")
    println(io, "## List of attributes")
    print_table(io, plot_attr_desc)
end

########################################
#       Axis attributes overview       #
########################################

# automatically generate an overview of the axis attributes, using a source md file
@info("Generating axis page")
path = joinpath(genpath, "axis.md")
srcdocpath = joinpath(srcgenpath, "src-axis.md")
include(joinpath(makiegallerydir, "src/Axis2D_attr_desc.jl"))
include(joinpath(makiegallerydir, "src/Axis3D_attr_desc.jl"))

open(path, "w") do io
    !ispath(srcdocpath) && error("source document doesn't exist!")
    src = read(srcdocpath, String)
    println(io, src)
    print(io)
    # Axis2D section
    println(io, "## `Axis2D`")
    println(io, "### `Axis2D` attributes groups")
    print_table(io, Axis2D_attr_desc)
    print(io)
    for (k, v) in Axis2D_attr_groups
        println(io, "#### `:$k`\n")
        print_table(io, v)
        println(io)
    end
    # Axis3D section
    println(io, "## `Axis3D`")
    println(io, "### `Axis3D` attributes groups")
    print_table(io, Axis3D_attr_desc)
    print(io)
    for (k, v) in Axis3D_attr_groups
        println(io, "#### `:$k`\n")
        print_table(io, v)
        println(io)
    end

end

########################################
#     Function signatures overview     #
########################################

# automatically generate an overview of the function signatures, using a source md file
@info("Generating signatures page")
path = joinpath(genpath, "signatures.md")
srcdocpath = joinpath(srcgenpath, "src-signatures.md")
open(path, "w") do io
    !ispath(srcdocpath) && error("source document doesn't exist!")
    println(io, "# Plot function signatures")
    src = read(srcdocpath, String)
    println(io, src)
    print(io, "\n")
    println(io, "```@docs")
    println(io, "convert_arguments")
    println(io, "```\n")

    println(io, "See [Plot attributes](@ref) for the available plot attributes.")
end

########################################
#          Colormap reference          #
########################################

@info "Generating colormap reference"

include(joinpath(srcgenpath, "colormap_generation.jl"))

generate_colorschemes_markdown(
    joinpath(srcgenpath, "src-colors.md"),
    joinpath(genpath, "colors.md")
)

################################################################################
#                 Building HTML documentation with Documenter                  #
################################################################################

@info("Running `makedocs` with Documenter.")

makedocs(
    doctest = false, clean = true,
    repo = "https://github.com/JuliaPlots/AbstractPlotting.jl/blob/{commit}{path}#{line}",
    format = Documenter.HTML(
        prettyurls = false,
        assets = [
            "assets/favicon.ico",
            "assets/syntaxtheme.css"
        ],
    ),
    sitename = "Makie.jl",
    expandfirst = [
        "plotting_functions.md",
    ],
    pages = Any[
        "Home" => "index.md",
        "Basics" => [
            "basic-tutorial.md",
            "animation.md",
            "interaction.md",
            "plotting_functions.md",
        ],
        "Documentation" => [
            "scenes.md",
            "generated/axis.md",
            "convenience.md",
            "generated/signatures.md",
            "generated/plot-attributes.md",
            "generated/colors.md",
            "lighting.md",
            "theming.md",
            "cameras.md",
            "recipes.md",
            "output.md",
            "backends.md",
            "troubleshooting.md"
        ],
        "MakieLayout" => [
            "Tutorial" => "makielayout/tutorial.md",
            "GridLayout" => "makielayout/grids.md",
            "LAxis" => "makielayout/laxis.md",
            "Special Plots" => "makielayout/special_plots.md",
            "LLegend" => "makielayout/llegend.md",
            "Layoutables Examples" => "makielayout/layoutables_examples.md",
            "Theming Layoutables" => "makielayout/theming.md",
            "How Layouting Works" => "makielayout/layouting.md",
            "Frequently Asked Questions" => "makielayout/faq.md",
            "API Reference" => "makielayout/reference.md",
        ],
        "Developer Documentation" => [
            "why-makie.md",
            "devdocs.md",
            "AbstractPlotting Reference" => "abstractplotting_api.md",
        ],
    ]
)

################################################################################
#                           Deploying documentation                            #
################################################################################

# add a custom configuration for Gitlab so the GPU-powered docs can be
# automatically uploaded to Github Pages

struct Gitlab <: Documenter.DeployConfig
    commit_branch::String
    pull_request_iid::String
    repo_slug::String
    commit_tag::String
    pipeline_source::String
end

function Gitlab()
    commit_branch = get(ENV, "CI_COMMIT_BRANCH", "")
    pull_request_iid = get(ENV, "CI_EXTERNAL_PULL_REQUEST_IID", "")
    repo_slug = get(ENV, "CI_PROJECT_PATH_SLUG", "")
    commit_tag = get(ENV, "CI_COMMIT_TAG", "")
    pipeline_source = get(ENV, "CI_PIPELINE_SOURCE", "")
    Gitlab(
        commit_branch,
        pull_request_iid,
        repo_slug,
        commit_tag,
        pipeline_source,
    )
end

function Documenter.deploy_folder(cfg::Gitlab;
        repo,
        repo_previews = repo,
        devbranch,
        push_preview,
        devurl,
        branch = "gh-pages",
        branch_previews = branch,
        kwargs...)

    marker(x) = x ? "✔" : "✘"

    io = IOBuffer()
    all_ok = true

    println(io, "\nGitlab config:")
    println(io, "  Commit branch: \"", cfg.commit_branch, "\"")
    println(io, "  Pull request IID: \"", cfg.pull_request_iid, "\"")
    println(io, "  Repo slug: \"", cfg.repo_slug, "\"")
    println(io, "  Commit tag: \"", cfg.commit_tag, "\"")
    println(io, "  Pipeline source: \"", cfg.pipeline_source, "\"")

    build_type = if cfg.pull_request_iid != ""
        :preview
    elseif cfg.commit_tag != ""
        :release
    else
        :devbranch
    end

    println(io, "Detected build type: ", build_type)

    if build_type == :release
        tag_nobuild = Documenter.version_tag_strip_build(cfg.commit_tag)
        ## If a tag exist it should be a valid VersionNumber
        tag_ok = tag_nobuild !== nothing

        println(io, "- $(marker(tag_ok)) ENV[\"CI_COMMIT_TAG\"] contains a valid VersionNumber")
        all_ok &= tag_ok

        is_preview = false
        subfolder = tag_nobuild
        deploy_branch = branch
        deploy_repo = repo
        
    elseif build_type == :preview
        pr_number = tryparse(Int, cfg.pull_request_iid)
        pr_ok = pr_number !== nothing
        all_ok &= pr_ok
        println(io, "- $(marker(pr_ok)) ENV[\"CI_EXTERNAL_PULL_REQUEST_IID\"]=\"$(cfg.pull_request_iid)\" is a number")
        btype_ok = push_preview
        all_ok &= btype_ok
        is_preview = true
        println(io, "- $(marker(btype_ok)) `push_preview` keyword argument to deploydocs is `true`")
        ## deploy to previews/PR
        subfolder = "previews/PR$(something(pr_number, 0))"
        deploy_branch = branch_previews
        deploy_repo = repo_previews
    else
        branch_ok = !isempty(cfg.commit_tag) || cfg.commit_branch == devbranch
        all_ok &= branch_ok
        println(io, "- $(marker(branch_ok)) ENV[\"CI_COMMIT_BRANCH\"] matches devbranch=\"$(devbranch)\"")
        is_preview = false
        subfolder = devurl
        deploy_branch = branch
        deploy_repo = repo
    end

    key_ok = haskey(ENV, "DOCUMENTER_KEY")
    println(io, "- $(marker(key_ok)) ENV[\"DOCUMENTER_KEY\"] exists")
    all_ok &= key_ok

    print(io, "Deploying to folder \"$(subfolder)\": $(marker(all_ok))")
    @info String(take!(io))

    return Documenter.DeployDecision(; all_ok = all_ok, branch = deploy_branch, repo = deploy_repo,
        subfolder = subfolder, is_preview = is_preview)
end

Documenter.authentication_method(::Gitlab) = Documenter.SSH

function Documenter.documenter_key(::Gitlab)
    return ENV["DOCUMENTER_KEY"]
end

deploydocs(
    repo = "github.com/JuliaPlots/MakieDocumentation",
    deploy_config = Gitlab(),
    push_preview = true
)
