#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of AudioLazy, the signal processing Python package.
# Copyright (C) 2012-2016 Danilo de Jesus da Silva Bellini
#
# AudioLazy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
AudioLazy documentation reStructuredText file creator

Note
----
You should call make_all_docs afterwards!

Warning
-------
Calling this OVERWRITES the RST files in the directory it's in, and don't
ask for confirmation!
"""

import os
import audiolazy
import re
from audiolazy import iteritems

# This file should be at the conf.py directory!
from conf import readme_file_contents, splitter, master_doc


def find_full_name(prefix, suffix="rst"):
  """
  Script path to actual path relative file name converter.

  Parameters
  ----------
  prefix :
    File name prefix (without extension), relative to the script location.
  suffix :
    File name extension (defaults to "rst").

  Returns
  -------
  A file name path relative to the actual location to a file
  inside the script location.

  Warning
  -------
  Calling this OVERWRITES the RST files in the directory it's in, and don't
  ask for confirmation!

  """
  return os.path.join(os.path.split(__file__)[0],
                      os.path.extsep.join([prefix, suffix]))


def save_to_rst(prefix, data):
  """
  Saves a RST file with the given prefix into the script file location.

  """
  with open(find_full_name(prefix), "w") as rst_file:
    rst_file.write(full_gpl_for_rst)
    rst_file.write(data)


#
# First chapter! Splits README.rst data into the gen_blocks iterable
#
readme_data = splitter(readme_file_contents)
rfc_copyright = readme_data.popitem()[1] # Last block is a small license msg
gen_blocks = iteritems(readme_data)

# Process GPL license comment at the beginning to put it in all RST files
gpl_to_add = "  File auto-generated by the rst_creator.py script."
full_gpl_for_rst = next(gen_blocks)[1] # It's before the first readable block
full_gpl_for_rst = "\n".join(full_gpl_for_rst[:-1] + [gpl_to_add] +
                             full_gpl_for_rst[-1:] + ["\n\n"])
gpl_for_rst = "\n  ".join(full_gpl_for_rst.strip()
                                          .strip(".").splitlines()[:-2])

# Process the first readable block (project name and small description)
rfc_name, rfc_description = next(gen_blocks) # Second block
rfc_name = " ".join([rfc_name, "|version|"]) # Puts version in title ...
rfc_name = [rfc_name, "=" * len(rfc_name)] # ... and the syntax of a title

# Process last block to have a nice looking, and insert license file link
license_file_name = "COPYING.txt"
license_full_file_name = "../" + license_file_name
linked_file_name = ":download:`{0} <{1}>`".format(license_file_name,
                                                  license_full_file_name)
rfc_copyright = ("\n  ".join(el.strip() for el in rfc_copyright
                                        if el.strip() != "")
                       .replace(license_file_name,linked_file_name)
                       .replace("- ", "")
                )

#
# Creates a RST for each block in README.rst besides the first (small
# description) and the last (license) ones, which were both already removed
# from "gen_blocks"
#
readme_names = [] # Keep the file names
for name, data in gen_blocks:
  fname = "".join(re.findall("[\w ]", name)).replace(" ", "_").lower()

  # Image location should be corrected before
  img_string = ".. image:: "
  for idx, el in enumerate(data):
    if el.startswith(img_string):
      data[idx]  = el.replace(img_string, img_string + "../")

  save_to_rst(fname, "\n".join([name, "=" * len(name)] + data).strip())
  readme_names.append(fname)


#
# Creates the master document
#

# First block
main_toc = """
.. toctree::
  :maxdepth: 2

  intro
  modules
"""
first_block = rfc_name + [""] + rfc_description + [main_toc]

# Second block
indices_block = """
.. only:: html

  Indices and tables
  ------------------

  * :ref:`genindex`
  * :ref:`modindex`
  * :ref:`search`
"""

# Saves the master document (with the TOC)
index_data = "\n".join(first_block + [indices_block])
save_to_rst(master_doc, index_data.strip())


#
# Creates the intro.rst
#
intro_block = """
Introduction
============

This is the main AudioLazy documentation, whose contents are mainly from the
repository documentation and source code docstrings, tied together with
`Sphinx <http://sphinx.pocoo.org>`_. The sections below can introduce you to
the AudioLazy Python DSP package.

.. toctree::
  :maxdepth: 4
{0}
  license
""".format(("\n" + 2 * " ").join([""] + readme_names))
save_to_rst("intro", intro_block.strip())


#
# Creates the license.rst
#
license_block = """
License and auto-generated reST files
=====================================

All project files, including source and documentation, are free software,
under GPLv3. This is free in the sense that the source code have to be always
available to you if you ask for it, as well as forks or otherwise derivative
new source codes, however stated in a far more precise way by experts in that
kind of law text. That's at the same time far from the technical language from
engineering, maths and computer science, and more details would be beyond the
needs of this document. You should find the following information in all
Python (*\*.py*) source code files and also in all reStructuredText (*\*.rst*)
files:

  ::

    {0}

This is so also for auto-generated reStructuredText documentation files.
However, besides most reStructuredText files being generated by a script,
their contents aren't auto-generated. These are spread in the source code,
both in reStructuredText and Python files, organized in a way that would make
the same manually written documentation be used as:

+ `Spyder <https://code.google.com/p/spyderlib/>`_ (Python IDE made for
  scientific purposes) *Rich Text* auto-documentation at its
  *Object inspector*. Docstrings were written in a reStructuredText syntax
  following its conventions for nice HTML rendering;

+ Python docstrings (besides some docstring creation like what happens in
  StrategyDict instances, that's really the original written data in the
  source);

+ Full documentation, thanks to `Sphinx <sphinx.pocoo.org>`_, that replaces
  the docstring conventions to other ones for creating in the that allows
  automatic conversion to:

  - HTML
  - PDF (LaTeX)
  - ePUB
  - Manual pages (man)
  - Texinfo
  - Pure text files

License is the same in all files that generates those documentations.
Some reStructuredText files, like the README.rst that generated this whole
chapter, were created manually. They're also free software as described in
GPLv3. The main project repository includes a message:

.. parsed-literal::

  {1}

This should be applied to all files that belongs to the AudioLazy project.
Although all the project files were up to now created and modified by a sole
person, this sole person had never wanted to keep such status for so long. If
you found a bug or otherwise have an issue or a patch to send, show the issue
or the pull request at the
`main AudioLazy repository <https://github.com/danilobellini/audiolazy>`_,
so that the bug would be fixed, or the new resource become available, not
only for a few people but for everyone.
""".format(gpl_for_rst, rfc_copyright)
save_to_rst("license", license_block.strip())


#
# Second chapter! Creates the modules.rst
#
modules_block = """
Modules Documentation
=====================

Below is the table of contents, with processed data from docstrings. They were
made and processed in a way that would be helpful as a stand-alone
documentation, but if it's your first time with this package, you should see
at least the :doc:`getting_started` before these, since the
full module documentation isn't written for beginners.

.. toctree::
  :maxdepth: 4
  :glob:

  audiolazy
  lazy_*
"""
save_to_rst("modules", modules_block.strip())


#
# Creates the RST file for the package
#
first_line = ":mod:`audiolazy` Package"
data = [
  first_line,
  "=" * len(first_line),
  ".. automodule:: audiolazy",
]
save_to_rst("audiolazy", "\n".join(data).strip())


#
# Creates the RST file for each module
#
for lzmodule in audiolazy.__modules__:
  first_line = ":mod:`{0}` Module".format(lzmodule)
  data = [
    first_line,
    "=" * len(first_line),
    ".. automodule:: audiolazy.{0}".format(lzmodule),
    "   :members:",
    "   :undoc-members:",
    "   :show-inheritance:",
  ]

  # See if there's any StrategyDict in the module
  module_data = getattr(audiolazy, lzmodule)
  for memb in module_data.__all__:
    memb_data = getattr(module_data, memb)
    if isinstance(memb_data, audiolazy.StrategyDict):
      sline = ":obj:`{0}.{1}` StrategyDict".format(lzmodule, memb)
      data += [
        "", sline,
        "-" * len(sline),
        ".. automodule:: audiolazy.{0}.{1}".format(lzmodule, memb),
        "   :members:",
        "   :undoc-members:",
      ]

  save_to_rst(lzmodule, "\n".join(data).strip())
