## @file
#
# This file produce action class to generate doxygen document for edk2 codebase.
# The action classes are shared by GUI and command line tools.
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
# distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

from plugins.EdkPlugins.basemodel import doxygen
import os
try:
    import wx
    gInGui = True
except:
    gInGui = False
import re
from plugins.EdkPlugins.edk2.model import inf
from plugins.EdkPlugins.edk2.model import dec
from plugins.EdkPlugins.basemodel.message import *

_ignore_dir = ['.svn', '_svn', 'cvs']
_inf_key_description_mapping_table = {
  'INF_VERSION':'Version of INF file specification',
  #'BASE_NAME':'Module Name',
  'FILE_GUID':'Module Guid',
  'MODULE_TYPE': 'Module Type',
  'VERSION_STRING': 'Module Version',
  'LIBRARY_CLASS': 'Produced Library Class',
  'EFI_SPECIFICATION_VERSION': 'UEFI Specification Version',
  'PI_SPECIFICATION_VERSION': 'PI Specification Version',
  'ENTRY_POINT': 'Module Entry Point Function',
  'CONSTRUCTOR': 'Library Constructor Function'
}

_dec_key_description_mapping_table = {
  'DEC_SPECIFICATION': 'Version of DEC file specification',
  'PACKAGE_GUID': 'Package Guid'
}
class DoxygenAction:
    """This is base class for all doxygen action.
    """

    def __init__(self, doxPath, chmPath, outputPath, projname, mode='html', log=None, verbose=False):
        """Constructor function.
        @param  doxPath         the obosolution path of doxygen execute file.
        @param  outputPath      the obosolution output path.
        @param  log             log function for output message
        """
        self._doxPath       = doxPath
        self._chmPath       = chmPath
        self._outputPath    = outputPath
        self._projname      = projname
        self._configFile    = None          # doxygen config file is used by doxygen exe file
        self._indexPageFile = None          # doxygen page file for index page.
        self._log           = log
        self._mode          = mode
        self._verbose       = verbose
        self._doxygenCallback = None
        self._chmCallback     = None

    def Log(self, message, level='info'):
        if self._log is not None:
            self._log(message, level)

    def IsVerbose(self):
        return self._verbose

    def Generate(self):
        """Generate interface called by outer directly"""
        self.Log(">>>>>> Start generate doxygen document for %s... Zzz....\n" % self._projname)

        # create doxygen config file at first
        self._configFile = doxygen.DoxygenConfigFile()
        self._configFile.SetOutputDir(self._outputPath)

        self._configFile.SetWarningFilePath(os.path.join(self._outputPath, 'warning.txt'))
        if self._mode.lower() == 'html':
            self._configFile.SetHtmlMode()
        else:
            self._configFile.SetChmMode()

        self.Log("    >>>>>> Initialize doxygen config file...Zzz...\n")
        self.InitializeConfigFile()

        self.Log("    >>>>>> Generate doxygen index page file...Zzz...\n")
        indexPagePath = self.GenerateIndexPage()
        if indexPagePath is None:
            self.Log("Fail to generate index page!\n", 'error')
            return False
        else:
            self.Log("Success to create doxygen index page file %s \n" % indexPagePath)

        # Add index page doxygen file to file list.
        self._configFile.AddFile(indexPagePath)

        # save config file to output path
        configFilePath = os.path.join(self._outputPath, self._projname + '.doxygen_config')
        self._configFile.Generate(configFilePath)
        self.Log("    <<<<<< Success Save doxygen config file to %s...\n" % configFilePath)

        # launch doxygen tool to generate document
        if self._doxygenCallback is not None:
            self.Log("    >>>>>> Start doxygen process...Zzz...\n")
            if not self._doxygenCallback(self._doxPath, configFilePath):
                return False
        else:
            self.Log("Fail to create doxygen process!", 'error')
            return False

        return True

    def InitializeConfigFile(self):
        """Initialize config setting for doxygen project. It will be invoked after config file
           object is created. Inherited class should implement it.
        """

    def GenerateIndexPage(self):
        """Generate doxygen index page. Inherited class should implement it."""
        return None

    def RegisterCallbackDoxygenProcess(self, callback):
        self._doxygenCallback = callback

    def RegisterCallbackCHMProcess(self, callback):
        self._chmCallback = callback

class PlatformDocumentAction(DoxygenAction):
    """Generate platform doxygen document, will be implement at future."""

class PackageDocumentAction(DoxygenAction):
    """Generate package reference document"""

    def __init__(self, doxPath, chmPath, outputPath, pObj, mode='html', log=None, arch=None, tooltag=None,
                 macros=[], onlyInclude=False, verbose=False):