/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.ofbiz.datafile;

import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.base.util.cache.Cache;
import org.ofbiz.base.util.cache.UtilCache;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * Flat File definition reader
 */

public final class ModelDataFileReader {

    public static final String module = ModelDataFileReader.class.getName();
    private static final Cache<URL, ModelDataFileReader> readers = UtilCache.createUtilCache("ModelDataFile", true);

    public static ModelDataFileReader getModelDataFileReader(URL readerURL) throws DataFileException {
        ModelDataFileReader reader = readers.get(readerURL);
        if (reader == null) {
            if (Debug.infoOn())
                Debug.logInfo("[ModelDataFileReader.getModelDataFileReader] : creating reader for " + readerURL, module);
            reader = new ModelDataFileReader(readerURL);
            readers.putIfAbsent(readerURL, reader);
        }
        if (Debug.infoOn())
            Debug.logInfo("[ModelDataFileReader.getModelDataFileReader] : returning reader for " + readerURL, module);
        return reader;
    }

    private final URL readerURL;
    private final Map<String, ModelDataFile> modelDataFiles;

    public ModelDataFileReader(URL readerURL) throws DataFileException {
        this.readerURL = readerURL;
        this.modelDataFiles = Collections.unmodifiableMap(createModelDataFiles());
    }

    private ModelDataFile createModelDataFile(Element dataFileElement) {
        ModelDataFile dataFile = new ModelDataFile();
        String tempStr;

        dataFile.name = UtilXml.checkEmpty(dataFileElement.getAttribute("name"));
        dataFile.typeCode = UtilXml.checkEmpty(dataFileElement.getAttribute("type-code"));
        dataFile.sender = UtilXml.checkEmpty(dataFileElement.getAttribute("sender"));
        dataFile.receiver = UtilXml.checkEmpty(dataFileElement.getAttribute("receiver"));

        tempStr = UtilXml.checkEmpty(dataFileElement.getAttribute("record-length"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            dataFile.recordLength = Integer.parseInt(tempStr);
        }
        tempStr = UtilXml.checkEmpty(dataFileElement.getAttribute("delimiter"));
        if (tempStr != null && tempStr.length() == 1) {
            dataFile.delimiter = tempStr.charAt(0);
        }

        tempStr = UtilXml.checkEmpty(dataFileElement.getAttribute("text-delimiter"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            dataFile.textDelimiter = tempStr;
        }

        dataFile.separatorStyle = UtilXml.checkEmpty(dataFileElement.getAttribute("separator-style"));
        dataFile.description = UtilXml.checkEmpty(dataFileElement.getAttribute("description"));

        NodeList rList = dataFileElement.getElementsByTagName("record");

        for (int i = 0; i < rList.getLength(); i++) {
            Element recordElement = (Element) rList.item(i);
            ModelRecord modelRecord = createModelRecord(recordElement);

            if (modelRecord != null) {
                dataFile.records.add(modelRecord);
            } else {
                Debug.logWarning("[ModelDataFileReader.createModelDataFile] Weird, modelRecord was null", module);
            }
        }

        for (ModelRecord modelRecord : dataFile.records) {

            if (modelRecord.parentName.length() > 0) {
                ModelRecord parentRecord = dataFile.getModelRecord(modelRecord.parentName);

                if (parentRecord != null) {
                    parentRecord.childRecords.add(modelRecord);
                    modelRecord.parentRecord = parentRecord;
                } else {
                    Debug.logError("[ModelDataFileReader.createModelDataFile] ERROR: Could not find parentRecord with name " + modelRecord.parentName, module);
                }
            }
        }

        return dataFile;
    }

    private Map<String, ModelDataFile> createModelDataFiles() throws DataFileException {
        Document document = null;
        Element docElement = null;
        try {
            document = UtilXml.readXmlDocument(this.readerURL);
        } catch (Exception e) {
            Debug.logWarning(e, "Error while reading " + this.readerURL + ": ", module);
            throw new DataFileException("Error while reading " + this.readerURL, e);
        }
        if (document != null) {
            docElement = document.getDocumentElement();
        }
        if (docElement == null) {
            Debug.logWarning("Document element not found in " + this.readerURL, module);
            throw new DataFileException("Document element not found in " + this.readerURL);
        }
        docElement.normalize();
        List<? extends Element> dataFileElements = UtilXml.childElementList(docElement, "data-file");
        if (dataFileElements.size() == 0) {
            Debug.logWarning("No <data-file> elements found in " + this.readerURL, module);
            throw new DataFileException("No <data-file> elements found in " + this.readerURL);
        }
        Map<String, ModelDataFile> result = new HashMap<String, ModelDataFile>();
        for (Element curDataFile : dataFileElements) {
            String dataFileName = UtilXml.checkEmpty(curDataFile.getAttribute("name"));
            if (result.containsKey(dataFileName)) {
                Debug.logWarning("DataFile " + dataFileName + " is defined more than once, most recent will over-write previous definition(s)", module);
            }
            ModelDataFile dataFile = createModelDataFile(curDataFile);
            if (dataFile != null) {
                result.put(dataFileName, dataFile);
                if (Debug.verboseOn()) {
                    Debug.logVerbose("Loaded dataFile: " + dataFileName, module);
                }
            } else {
                Debug.logWarning("Could not create dataFile for dataFileName " + dataFileName, module);
                throw new DataFileException("Could not create dataFile for " + dataFileName + " defined in " + this.readerURL);
            }
        }
        return result;
    }

    private ModelField createModelField(Element fieldElement) {
        ModelField field = new ModelField();
        String tempStr;

        field.name = UtilXml.checkEmpty(fieldElement.getAttribute("name"));

        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("position"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            field.position = Integer.parseInt(tempStr);
        }
        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("length"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            field.length = Integer.parseInt(tempStr);
        }

        field.type = UtilXml.checkEmpty(fieldElement.getAttribute("type"));
        field.format = UtilXml.checkEmpty(fieldElement.getAttribute("format"));
        field.validExp = UtilXml.checkEmpty(fieldElement.getAttribute("valid-exp"));
        field.description = UtilXml.checkEmpty(fieldElement.getAttribute("description"));
        field.defaultValue = UtilXml.checkEmpty(fieldElement.getAttribute("default-value"));
        field.refField = UtilXml.checkEmpty(fieldElement.getAttribute("ref-field"));

        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("prim-key"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            field.isPk = Boolean.parseBoolean(tempStr);
        }

        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("ignored"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            field.ignored = Boolean.parseBoolean(tempStr);
        }

        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("expression"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            field.expression = Boolean.parseBoolean(tempStr);
        }

        return field;
    }

    private ModelRecord createModelRecord(Element recordElement) {
        ModelRecord record = new ModelRecord();
        String tempStr;

        record.name = UtilXml.checkEmpty(recordElement.getAttribute("name"));
        record.typeCode = UtilXml.checkEmpty(recordElement.getAttribute("type-code"));

        record.tcMin = UtilXml.checkEmpty(recordElement.getAttribute("tc-min"));
        if (record.tcMin.length() > 0)
            record.tcMinNum = Long.parseLong(record.tcMin);
        record.tcMax = UtilXml.checkEmpty(recordElement.getAttribute("tc-max"));
        if (record.tcMax.length() > 0)
            record.tcMaxNum = Long.parseLong(record.tcMax);

        tempStr = UtilXml.checkEmpty(recordElement.getAttribute("tc-isnum"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            record.tcIsNum = Boolean.parseBoolean(tempStr);
        }

        tempStr = UtilXml.checkEmpty(recordElement.getAttribute("tc-position"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            record.tcPosition = Integer.parseInt(tempStr);
        }
        tempStr = UtilXml.checkEmpty(recordElement.getAttribute("tc-length"));
        if (UtilValidate.isNotEmpty(tempStr)) {
            record.tcLength = Integer.parseInt(tempStr);
        }

        record.description = UtilXml.checkEmpty(recordElement.getAttribute("description"));
        record.parentName = UtilXml.checkEmpty(recordElement.getAttribute("parent-name"));
        record.limit = UtilXml.checkEmpty(recordElement.getAttribute("limit"));

        NodeList fList = recordElement.getElementsByTagName("field");
        int priorEnd = -1;

        for (int i = 0; i < fList.getLength(); i++) {
            Element fieldElement = (Element) fList.item(i);
            ModelField modelField = createModelField(fieldElement);

            // if the position is not specified, assume the start position based on last entry
            if ((i > 0) && (modelField.position == -1)) {
                modelField.position = priorEnd;
            }
            priorEnd = modelField.position + modelField.length;
            record.fields.add(modelField);
        }

        return record;
    }

    /**
     * Creates a Collection with the dataFileName of each DataFile defined in the
     * specified XML DataFile Descriptor file.
     * 
     * @return A Collection of dataFileName Strings
     */
    public Collection<String> getDataFileNames() {
        return this.modelDataFiles.keySet();
    }

    /**
     * Creates a Iterator with the dataFileName of each DataFile defined in the specified
     * XML DataFile Descriptor file.
     * 
     * @return A Iterator of dataFileName Strings
     */
    public Iterator<String> getDataFileNamesIterator() {
        return this.modelDataFiles.keySet().iterator();
    }

    /**
     * Gets an DataFile object based on a definition from the specified XML DataFile
     * descriptor file.
     * 
     * @param dataFileName
     *            The dataFileName of the DataFile definition to use.
     * @return An DataFile object describing the specified dataFile of the specified
     *         descriptor file.
     */
    public ModelDataFile getModelDataFile(String dataFileName) {
        return this.modelDataFiles.get(dataFileName);
    }

    public Map<String, ModelDataFile> getModelDataFiles() {
        return this.modelDataFiles;
    }
}
