/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.yangutils.translator.tojava;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.onosproject.yangutils.datamodel.javadatamodel.JavaFileInfo;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangEnum;
import org.onosproject.yangutils.datamodel.YangEnumeration;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.translator.tojava.javamodel.YangJavaTypeTranslator;
import org.onosproject.yangutils.datamodel.javadatamodel.YangPluginConfig;

import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ENUM_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.JavaAttributeInfo.getAttributeInfoForTheData;
import static org.onosproject.yangutils.translator.tojava.utils.JavaCodeSnippetGen.generateEnumAttributeString;
import static org.onosproject.yangutils.translator.tojava.utils.JavaFileGenerator.generateEnumClassFile;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getEnumJavaAttribute;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getPrefixForIdentifier;
import static org.onosproject.yangutils.utils.io.impl.FileSystemUtil.closeFile;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_FIRST_DIGIT;
import static org.onosproject.yangutils.utils.UtilConstants.YANG_AUTO_PREFIX;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.createPackage;

/**
 * Represents implementation of java code fragments temporary implementations. Maintains the temp files required
 * specific for enumeration java snippet generation.
 */
public class TempJavaEnumerationFragmentFiles extends TempJavaFragmentFiles {

    /**
     * File name for temporary enum class.
     */
    private static final String ENUM_CLASS_TEMP_FILE_NAME = "EnumClass";

    /**
     * File name for enum class file name suffix.
     */
    private static final String ENUM_CLASS_FILE_NAME_SUFFIX = EMPTY_STRING;

    /**
     * Current enum's value.
     */
    private int enumValue;

    /**
     * Contains data of enumSet.
     */
    private Map<String, Integer> enumStringMap = new HashMap<>();

    /**
     * Contains data of enumSet.
     */
    private List<String> enumStringList;

    /**
     * Temporary file handle for enum class file.
     */
    private File enumClassTempFileHandle;

    /**
     * Java file handle for enum class.
     */
    private File enumClassJavaFileHandle;

    /**
     * Creates an instance of temporary java code fragment.
     *
     * @param javaFileInfo generated java file info
     * @throws IOException when fails to create new file handle
     */
    TempJavaEnumerationFragmentFiles(JavaFileInfo javaFileInfo)
            throws IOException {

        super(javaFileInfo);
        setEnumSetJavaMap(new HashMap<>());
        setEnumStringList(new ArrayList<>());
        /*
         * Initialize enum when generation file type matches to enum class mask.
         */
        addGeneratedTempFile(ENUM_IMPL_MASK);
        setEnumClassTempFileHandle(getTemporaryFileHandle(ENUM_CLASS_TEMP_FILE_NAME));
    }

    /**
     * Returns enum class java file handle.
     *
     * @return enum class java file handle
     */
    private File getEnumClassJavaFileHandle() {
        return enumClassJavaFileHandle;
    }

    /**
     * Sets enum class java file handle.
     *
     * @param enumClassJavaFileHandle enum class java file handle
     */
    private void setEnumClassJavaFileHandle(File enumClassJavaFileHandle) {
        this.enumClassJavaFileHandle = enumClassJavaFileHandle;
    }

    /**
     * Returns enum's value.
     *
     * @return enum's value
     */
    private int getEnumValue() {
        return enumValue;
    }

    /**
     * Sets enum's value.
     *
     * @param enumValue enum's value
     */
    private void setEnumValue(int enumValue) {
        this.enumValue = enumValue;
    }

    /**
     * Returns enum set java map.
     *
     * @return the enum set java map
     */
    public Map<String, Integer> getEnumSetJavaMap() {
        return enumStringMap;
    }

    /**
     * Sets enum set java map.
     *
     * @param map the enum set java map to set
     */
    private void setEnumSetJavaMap(Map<String, Integer> map) {
        this.enumStringMap = map;
    }

    /**
     * Returns temporary file handle for enum class file.
     *
     * @return temporary file handle for enum class file
     */
    public File getEnumClassTempFileHandle() {
        return enumClassTempFileHandle;
    }

    /**
     * Sets temporary file handle for enum class file.
     *
     * @param enumClassTempFileHandle temporary file handle for enum class file
     */
    private void setEnumClassTempFileHandle(File enumClassTempFileHandle) {
        this.enumClassTempFileHandle = enumClassTempFileHandle;
    }

    /**
     * Adds enum class attributes to temporary file.
     *
     * @param curEnumName current YANG enum
     * @throws IOException when fails to do IO operations.
     */
    private void addAttributesForEnumClass(String curEnumName, YangPluginConfig pluginConfig) throws IOException {
        appendToFile(getEnumClassTempFileHandle(),
                generateEnumAttributeString(curEnumName, getEnumValue(), pluginConfig));
    }

    /**
     * Adds enum attributes to temporary files.
     *
     * @param curNode      current YANG node
     * @param pluginConfig plugin configurations
     * @throws IOException when fails to do IO operations
     */
    void addEnumAttributeToTempFiles(YangNode curNode, YangPluginConfig pluginConfig) throws IOException {

        super.addJavaSnippetInfoToApplicableTempFiles(getJavaAttributeForEnum(pluginConfig), pluginConfig);
        if (curNode instanceof YangEnumeration) {
            YangEnumeration enumeration = (YangEnumeration) curNode;
            for (YangEnum curEnum : enumeration.getEnumSet()) {
                String enumName = curEnum.getNamedValue();
                String prefixForIdentifier;
                if (enumName.matches(REGEX_FOR_FIRST_DIGIT)) {
                    prefixForIdentifier = getPrefixForIdentifier(pluginConfig.getConflictResolver());
                    if (prefixForIdentifier != null) {
                        curEnum.setNamedValue(prefixForIdentifier + enumName);
                    } else {
                        curEnum.setNamedValue(YANG_AUTO_PREFIX + enumName);
                    }
                }
                setEnumValue(curEnum.getValue());
                addToEnumStringList(curEnum.getNamedValue());
                addToEnumSetJavaMap(curEnum.getNamedValue(), curEnum.getValue());
                addJavaSnippetInfoToApplicableTempFiles(curEnum.getNamedValue(), pluginConfig);
            }
        } else {
            throw new TranslatorException("current node should be of enumeration type.");
        }
    }

    /**
     * Returns java attribute for enum class.
     *
     * @param pluginConfig plugin configurations
     * @return java attribute
     */
    public JavaAttributeInfo getJavaAttributeForEnum(YangPluginConfig pluginConfig) {
        YangJavaTypeTranslator<?> javaType = new YangJavaTypeTranslator<>();
        javaType.setDataType(YangDataTypes.INT32);
        javaType.setDataTypeName("int");
        javaType.updateJavaQualifiedInfo(pluginConfig.getConflictResolver());
        return getAttributeInfoForTheData(
                javaType.getJavaQualifiedInfo(),
                javaType.getDataTypeName(), javaType,
                getIsQualifiedAccessOrAddToImportList(javaType.getJavaQualifiedInfo()),
                false);
    }

    /**
     * Adds current enum name to java list.
     *
     * @param curEnumName current enum name
     */
    private void addToEnumSetJavaMap(String curEnumName, int value) {
        getEnumSetJavaMap().put(getEnumJavaAttribute(curEnumName).toUpperCase(), value);
    }

    /**
     * Adds the new attribute info to the target generated temporary files.
     *
     * @param curEnumName the attribute name that needs to be added to temporary files
     * @throws IOException IO operation fail
     */
    private void addJavaSnippetInfoToApplicableTempFiles(String curEnumName, YangPluginConfig pluginConfig)
            throws IOException {
        addAttributesForEnumClass(getEnumJavaAttribute(curEnumName), pluginConfig);
    }

    /**
     * Constructs java code exit.
     *
     * @param fileType generated file type
     * @param curNode  current YANG node
     * @throws IOException when fails to generate java files
     */
    @Override
    public void generateJavaFile(int fileType, YangNode curNode) throws IOException {
        createPackage(curNode);
        setEnumClassJavaFileHandle(getJavaFileHandle(getJavaClassName(ENUM_CLASS_FILE_NAME_SUFFIX)));
        setEnumClassJavaFileHandle(generateEnumClassFile(getEnumClassJavaFileHandle(), curNode));
        freeTemporaryResources(false);
    }

    /**
     * Removes all temporary file handles.
     *
     * @param isErrorOccurred flag to tell translator that error has occurred while file generation
     * @throws IOException when failed to delete the temporary files
     */
    @Override
    public void freeTemporaryResources(boolean isErrorOccurred) throws IOException {
        closeFile(getEnumClassJavaFileHandle(), isErrorOccurred);
        closeFile(getEnumClassTempFileHandle(), true);
        super.freeTemporaryResources(isErrorOccurred);
    }

    /**
     * Adds  to enum string list.
     *
     * @param curEnumValue current enum value
     */
    private void addToEnumStringList(String curEnumValue) {
        getEnumStringList().add(getEnumJavaAttribute(curEnumValue).toUpperCase());
    }

    /**
     * Returns enum string list.
     *
     * @return the enumStringList
     */
    public List<String> getEnumStringList() {
        return enumStringList;
    }

    /**
     * Sets enum string list.
     *
     * @param enumStringList the enumStringList to set
     */
    private void setEnumStringList(List<String> enumStringList) {
        this.enumStringList = enumStringList;
    }
}
