/*
 * Copyright (c) 2011-2015, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once

#include "XmlSerializingContext.h"
#include "XmlDomainImportContext.h"
#include "XmlDomainExportContext.h"
#include "SyncerSet.h"
#include "Results.h"
#include <list>
#include <set>
#include <map>
#include <string>

class CConfigurableElement;
class CDomainConfiguration;
class CParameterBlackboard;
class CSelectionCriteriaDefinition;

class CConfigurableDomain : public CElement
{
    typedef std::list<CConfigurableElement *>::const_iterator ConfigurableElementListIterator;
    typedef std::map<const CConfigurableElement *, CSyncerSet *>::const_iterator
        ConfigurableElementToSyncerSetMapIterator;

public:
    CConfigurableDomain() = default;
    CConfigurableDomain(const std::string &strName);
    ~CConfigurableDomain() override;

    // Sequence awareness
    void setSequenceAwareness(bool bSequenceAware);
    bool getSequenceAwareness() const;

    // Configuration Management
    bool createConfiguration(const std::string &strName,
                             const CParameterBlackboard *pMainBlackboard, std::string &strError);
    bool deleteConfiguration(const std::string &strName, std::string &strError);
    bool renameConfiguration(const std::string &strName, const std::string &strNewName,
                             std::string &strError);

    /** Restore a configuration
     *
     * @param[in] configurationName the configuration name
     * @param[in] mainBlackboard the application main blackboard
     * @param[in] autoSync boolean which indicates if auto sync mechanism is on
     * @param[out] errors, errors encountered during restoration
     * @return true if success false otherwise
     */
    bool restoreConfiguration(const std::string &configurationName,
                              CParameterBlackboard *mainBlackboard, bool autoSync,
                              core::Results &errors) const;

    bool saveConfiguration(const std::string &strName, const CParameterBlackboard *pMainBlackboard,
                           std::string &strError);
    bool setElementSequence(const std::string &strConfiguration,
                            const std::vector<std::string> &astrNewElementSequence,
                            std::string &strError);
    bool getElementSequence(const std::string &strConfiguration, std::string &strResult) const;
    bool setApplicationRule(const std::string &strConfiguration,
                            const std::string &strApplicationRule,
                            const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition,
                            std::string &strError);
    bool clearApplicationRule(const std::string &strConfiguration, std::string &strError);
    bool getApplicationRule(const std::string &strConfiguration, std::string &strResult) const;

    // Last applied configuration name
    std::string getLastAppliedConfigurationName() const;

    // Pending configuration name
    std::string getPendingConfigurationName() const;

    // Associated Configurable elements
    void gatherConfigurableElements(
        std::set<const CConfigurableElement *> &configurableElementSet) const;
    void listAssociatedToElements(std::string &strResult) const;

    /** Add a configurable element to the domain
     *
     * @param[in] pConfigurableElement pointer to the element to add
     * @param[in] pMainBlackboard pointer to the application main blackboard
     * @param[out] infos useful information we can provide to client
     * @return true if succeed false otherwise
     */
    bool addConfigurableElement(CConfigurableElement *pConfigurableElement,
                                const CParameterBlackboard *pMainBlackboard, core::Results &infos);

    bool removeConfigurableElement(CConfigurableElement *pConfigurableElement,
                                   std::string &strError);

    // Blackboard Configuration and Base Offset retrieval
    CParameterBlackboard *findConfigurationBlackboard(
        const std::string &strConfiguration, const CConfigurableElement *pConfigurableElement,
        size_t &baseOffset, bool &bIsLastApplied, std::string &strError) const;

    /** Split the domain in two.
     * Remove an element of a domain and create a new domain which owns the element.
     *
     * @param[in] pConfigurableElement pointer to the element to remove
     * @param[out] infos useful information we can provide to client
     * @return true if succeed false otherwise
     */
    bool split(CConfigurableElement *pConfigurableElement, core::Results &infos);

    // Ensure validity on whole domain from main blackboard
    void validate(const CParameterBlackboard *pMainBlackboard);

    /** Apply the configuration if required
     *
     * @param[in] pParameterBlackboard the blackboard to synchronize
     * @param[in] pSyncerSet pointer to the set containing application syncers
     * @param[in] bForced boolean used to force configuration application
     * @param[out] info string containing useful information we can provide to client
     */
    void apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet *pSyncerSet, bool bForced,
               std::string &info) const;

    // Return applicable configuration validity for given configurable element
    bool isApplicableConfigurationValid(const CConfigurableElement *pConfigurableElement) const;

    // From IXmlSink
    bool fromXml(const CXmlElement &xmlElement,
                 CXmlSerializingContext &serializingContext) override;

    // From IXmlSource
    void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const override;
    void childrenToXml(CXmlElement &xmlElement,
                       CXmlSerializingContext &serializingContext) const override;

    // Class kind
    std::string getKind() const override;

protected:
    // Content dumping
    std::string logValue(utility::ErrorContext &errorContext) const override;

private:
    // Get pending configuration
    const CDomainConfiguration *getPendingConfiguration() const;

    // Search for an applicable configuration
    const CDomainConfiguration *findApplicableDomainConfiguration() const;

    // Returns true if children dynamic creation is to be dealt with (here, will allow child
    // deletion upon clean)
    bool childrenAreDynamic() const override;

    // Ensure validity on areas related to configurable element
    void validateAreas(const CConfigurableElement *pConfigurableElement,
                       const CParameterBlackboard *pMainBlackboard);

    // Attempt validation for all configurable element's areas, relying on already existing valid
    // configuration inside domain
    void autoValidateAll();

    // Attempt validation for one configurable element's areas, relying on already existing valid
    // configuration inside domain
    void autoValidateAreas(const CConfigurableElement *pConfigurableElement);

    // Attempt configuration validation for all configurable elements' areas, relying on already
    // existing valid configuration inside domain
    bool autoValidateConfiguration(CDomainConfiguration *pDomainConfiguration);

    // Search for a valid configuration for given configurable element
    const CDomainConfiguration *findValidDomainConfiguration(
        const CConfigurableElement *pConfigurableElement) const;

    // In case configurable element was removed
    void computeSyncSet();

    // Check configurable element already attached
    bool containsConfigurableElement(
        const CConfigurableElement *pConfigurableCandidateElement) const;

    /** Merge any descended configurable element to this one
     *
     * @param[in] newElement pointer to element which has potential descendants which can be merged
     * @param[out] infos useful information we can provide to client
     */
    void mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement *newElement,
                                                              core::Results &infos);

    void mergeConfigurations(CConfigurableElement *pToConfigurableElement,
                             CConfigurableElement *pFromConfigurableElement);

    /** Actually realize the association between the domain and a configurable  element
     *
     * @param[in] pConfigurableElement pointer to the element to add
     * @param[out] infos useful information we can provide to client
     * @param[in] (optional) pMainBlackboard, pointer to the application main blackboard
     *            Default value is NULL, when provided, blackboard area concerning the configurable
     *            element are validated.
     */
    void doAddConfigurableElement(CConfigurableElement *pConfigurableElement, core::Results &infos,
                                  const CParameterBlackboard *pMainBlackboard = nullptr);

    void doRemoveConfigurableElement(CConfigurableElement *pConfigurableElement,
                                     bool bRecomputeSyncSet);

    // XML parsing
    /**
     * Deserialize domain configurations from an Xml document and add them to
     * the domain.
     *
     * @param[in] xmlElement the XML element to be parsed
     * @param[in] serializingContext context for the deserialization
     *
     * @return false if an error occurs, true otherwise.
     */
    bool parseDomainConfigurations(const CXmlElement &xmlElement,
                                   CXmlDomainImportContext &serializingContext);
    /**
     * Deserialize domain elements from an Xml document and add them to
     * the domain.
     *
     * @param[in] xmlElement the XML element to be parsed
     * @param[in] serializingContext context for the deserialization
     *
     * @return false if an error occurs, true otherwise.
     */
    bool parseConfigurableElements(const CXmlElement &xmlElement,
                                   CXmlDomainImportContext &serializingContext);
    /**
     * Deserialize settings from an Xml document and add them to
     * the domain.
     *
     * @param[in] xmlElement the XML element to be parsed
     * @param[in] xmlDomainImportContext context for the deserialization
     *
     * @return false if an error occurs, true otherwise.
     */
    bool parseSettings(const CXmlElement &xmlElement, CXmlDomainImportContext &serializingContext);

    // XML composing
    void composeDomainConfigurations(CXmlElement &xmlElement,
                                     CXmlSerializingContext &serializingContext) const;
    void composeConfigurableElements(CXmlElement &xmlElement) const;
    void composeSettings(CXmlElement &xmlElement, CXmlDomainExportContext &context) const;

    // Syncer set retrieval from configurable element
    CSyncerSet *getSyncerSet(const CConfigurableElement *pConfigurableElement) const;

    // Configuration retrieval
    CDomainConfiguration *findConfiguration(const std::string &strConfiguration,
                                            std::string &strError);
    const CDomainConfiguration *findConfiguration(const std::string &strConfiguration,
                                                  std::string &strError) const;

    // Configurable elements
    std::list<CConfigurableElement *> _configurableElementList;

    // Associated syncer sets
    std::map<const CConfigurableElement *, CSyncerSet *> _configurableElementToSyncerSetMap;

    // Sequence awareness
    bool _bSequenceAware{false};

    // Syncer set used to ensure propoer synchronization of restored configurable elements
    CSyncerSet _syncerSet;

    // Last applied configuration
    mutable const CDomainConfiguration *_pLastAppliedConfiguration{nullptr};
};
