#!/usr/bin/env python

import datetime
import inspect
import os
import sys

sys.path.insert(0, os.path.abspath('../..'))

import pop_tools

# -- General configuration ---------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.autosummary',
    'sphinx.ext.doctest',
    'sphinx.ext.intersphinx',
    'sphinx.ext.extlinks',
    'IPython.sphinxext.ipython_console_highlighting',
    'IPython.sphinxext.ipython_directive',
    'sphinx.ext.mathjax',  # for math equations
    'sphinx.ext.napoleon',
    'myst_nb',
    'sphinx.ext.linkcode',
    'sphinxext.opengraph',
    'sphinx_copybutton',
    'sphinx_comments',
]

# MyST config
myst_enable_extensions = [
    'amsmath',
    'colon_fence',
    'deflist',
    'dollarmath',
    'html_admonition',
    'html_image',
    'linkify',
    'replacements',
    'smartquotes',
    'substitution',
]
myst_url_schemes = ('http', 'https', 'mailto')

# sphinx-copybutton configurations
copybutton_prompt_text = r'>>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: | {5,8}: '
copybutton_prompt_is_regexp = True

# myst-nb configurations
# https://myst-nb.readthedocs.io/en/latest/use/execute.html
jupyter_execute_notebooks = 'cache'
execution_timeout = 600
# Don't execute these notebooks
execution_excludepatterns = [
    'examples/pop_div_curl_xr_xgcm_metrics_compare*',
    'examples/CloseHeatBudget_POP2*',
    'examples/cesm-cmip-cf-xarray*',
]

comments_config = {
    'utterances': {'repo': 'NCAR/pop-tools', 'optional': 'config', 'label': '💬 comment'},
    'hypothesis': False,
}

extlinks = {
    'issue': ('https://github.com/NCAR/pop-tools/issues/%s', 'GH#'),
    'pr': ('https://github.com/NCAR/pop-tools/pull/%s', 'GH#'),
}

# Autosummary pages will be generated by sphinx-autogen instead of sphinx-build
autosummary_generate = []
autodoc_typehints = 'none'

# Napoleon configurations

napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_use_param = False
napoleon_use_rtype = False
napoleon_preprocess_types = True

# configuration for sphinxext.opengraph
ogp_site_url = 'https://pop-tools.readthedocs.io/en/latest/'
# ogp_image = ""


# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = {
    '.rst': 'restructuredtext',
    '.ipynb': 'myst-nb',
    '.myst': 'myst-nb',
}


# The master toctree document.
master_doc = 'index'

# General information about the project.
current_year = datetime.datetime.now().year
project = 'pop-tools'
copyright = f'2018-{current_year}, University Corporation for Atmospheric Research'
author = 'pop-tools developers'

# The version info for the project you're documenting, acts as replacement
# for |version| and |release|, also used in various other places throughout
# the built documents.
#
# The short X.Y version.
version = pop_tools.__version__.split('+')[0]
# The full version, including alpha/beta/rc tags.
release = pop_tools.__version__


# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
# exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.ipynb_checkpoints']
exclude_patterns = ['_build', '**.ipynb_checkpoints', 'Thumbs.db', '.DS_Store']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False


# -- Options for HTML output -------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_book_theme'
html_title = ''

html_context = {
    'github_user': 'NCAR',
    'github_repo': 'pop-tools',
    'github_version': 'master',
    'doc_path': 'docs',
}
html_theme_options = dict(
    # analytics_id=''  this is configured in rtfd.io
    # canonical_url="",
    repository_url='https://github.com/NCAR/pop-tools',
    repository_branch='master',
    path_to_docs='docs',
    use_edit_page_button=True,
    use_repository_button=True,
    use_issues_button=True,
    home_page_in_toc=False,
    extra_navbar='',
    navbar_footer_text='',
    extra_footer="""Theme by the <a href="https://ebp.jupyterbook.org">Executable Book Project</a>""",
)

html_logo = 'images/nsf.png'

# Theme options are theme-specific and customize the look and feel of a
# theme further.  For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".


html_static_path = ['../_static']
html_css_files = ['css/style.css']


today_fmt = '%Y-%m-%d'
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = today_fmt


# -- Options for HTMLHelp output ---------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'pop-tools-doc'


# -- Options for LaTeX output ------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',
    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',
    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',
    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto, manual, or own class]).
latex_documents = [(master_doc, 'pop-tools.tex', 'POP-tools Documentation', author, 'manual')]


# -- Options for manual page output ------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, 'pop-tools', 'POP-tools Documentation', [author], 1)]


# -- Options for Texinfo output ----------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (
        master_doc,
        'POP-tools',
        'POP-tools Documentation',
        author,
        'POP-tools',
        'One line description of project.',
        'Miscellaneous',
    )
]


ipython_execlines = [
    'import numpy as np',
    'import pandas as pd',
    'import xarray as xr',
    'import pop_tools',
]


intersphinx_mapping = {
    'python': ('https://docs.python.org/3/', None),
    'xarray': ('http://xarray.pydata.org/en/stable/', None),
    'xgcm': ('https://xgcm.readthedocs.io/en/latest/', None),
}


# based on numpy doc/source/conf.py
def linkcode_resolve(domain, info):
    """
    Determine the URL corresponding to Python object
    """
    if domain != 'py':
        return None

    modname = info['module']
    fullname = info['fullname']

    submod = sys.modules.get(modname)
    if submod is None:
        return None

    obj = submod
    for part in fullname.split('.'):
        try:
            obj = getattr(obj, part)
        except AttributeError:
            return None

    try:
        fn = inspect.getsourcefile(inspect.unwrap(obj))
    except TypeError:
        fn = None
    if not fn:
        return None

    try:
        source, lineno = inspect.getsourcelines(obj)
    except OSError:
        lineno = None

    if lineno:
        linespec = f'#L{lineno}-L{lineno + len(source) - 1}'
    else:
        linespec = ''

    fn = os.path.relpath(fn, start=os.path.dirname(pop_tools.__file__))

    if '+' in pop_tools.__version__:
        return f'https://github.com/NCAR/pop-tools/blob/master/pop_tools/{fn}{linespec}'
    else:
        return (
            f'https://github.com/NCAR/pop-tools/blob/'
            f'v{pop_tools.__version__}/pop_tools/{fn}{linespec}'
        )


def html_page_context(app, pagename, templatename, context, doctree):
    # Disable edit button for docstring generated pages
    if 'generated' in pagename:
        context['theme_use_edit_page_button'] = False


def setup(app):
    app.connect('html-page-context', html_page_context)
