package com.capgemini.framework.common;

import com.capgemini.reports.exceptions.FileLoadingException;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * Class managing substitutions of certain tags found in a template file.
 **/
@Slf4j
public class FileTemplate {

    /**
     * Starting separator for query parameter.
     **/
    private static final String PARAM_START = "[[";

    /**
     * Ending separator for query parameter.
     **/
    private static final String PARAM_END = "]]";

    /**
     * Mapping between tags and their values.
     **/
    private Map<String, String> tagValues = new HashMap<>();

    /**
     * Template file path.
     **/
    private String templateFilePath;

    /**
     * Template content.
     **/
    private String templateContent;

    /**
     * Default empty constructor.
     **/
    protected FileTemplate() {
        // Nothing to do
    }

    /**
     * Compute a tag from its name.
     *
     * @param aTagName Name of the tag
     * @return Name encapsulated by starting and ending markers
     **/
    private static String getTag(final String aTagName) {
        return PARAM_START + aTagName + PARAM_END;
    }

    /**
     * Generate file content for a specific class.
     *
     * @return Template code
     **/
    public String generateCode() {
        // Check if template is correctly initialized
        if (templateContent == null) {
            log.error("Unable to generate the code, the template content is empty");
            return null;
        }

        String theFinalContent = templateContent;

        // Replace template tags
        for (String theCurrentTag : tagValues.keySet()) {
            // Get next tag value
            String currentTagValue = tagValues.get(theCurrentTag);

            // Check if tag value is set properly
            if (currentTagValue == null) {
                log.warn("Tag value is null for " + theCurrentTag);
            } else {
                // Replace current tag with its value
                theFinalContent = theFinalContent.replace(getTag(theCurrentTag), currentTagValue);
            }
        }

        // Check content after tag replacement and display a warning if there is a missing tag value
        isMissingTag(theFinalContent);
        return theFinalContent;
    }

    /**
     * Add a new parameter.
     *
     * @param aTagName       Parameter name
     * @param aReplacedValue Parameter value
     */
    protected void setTagValue(final String aTagName, final String aReplacedValue) {
        tagValues.put(aTagName, aReplacedValue);
    }

    /**
     * Check if there is a remaining tag value which has not been replaced.
     *
     * @param aTemplateContent Template code
     * @return True when a missing tag has been detected
     **/
    private boolean isMissingTag(final String aTemplateContent) {
        boolean isMissing = false;
        int theStartPos = aTemplateContent.indexOf(PARAM_START);
        int theEndPos = aTemplateContent.indexOf(PARAM_END);
        if ((theStartPos >= 0) && (theEndPos > 0)) {
            String theTagName = aTemplateContent.substring(theStartPos + PARAM_START.length(), theEndPos);
            log.warn("Tag value is missing for {} in file {}", theTagName, templateFilePath);
            isMissing = true;
        }
        return isMissing;
    }

    /**
     * Setter for template file.
     *
     * @param aTemplateFilePath Template file path
     **/
    protected final void setTemplateFilePath(final String aTemplateFilePath) {
        templateFilePath = aTemplateFilePath;
        if (templateFilePath != null) {
            try {
                templateContent = ResourceHelper.getResourceContent(aTemplateFilePath);
            } catch (FileLoadingException e) {
                log.error("Unable to initialize template, the required file at: " + templateFilePath + " is missing", e);
            }
        }
    }

    protected final void setTemplateContent(final String content) {
        this.templateContent = content;
    }
}
