/* BdfServer - Copyright (c) 2012-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.tools.exportation.table;

import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.api.storage.StorageContent;
import fr.exemole.bdfserver.api.storage.TableExportStorage;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.List;
import net.fichotheque.Fichotheque;
import net.fichotheque.Subset;
import net.fichotheque.SubsetKey;
import net.fichotheque.exportation.table.TableDef;
import net.fichotheque.exportation.table.TableDefItem;
import net.fichotheque.exportation.table.TableExportContentDescription;
import net.fichotheque.exportation.table.TableExportContext;
import net.fichotheque.exportation.table.TableExportDef;
import net.fichotheque.exportation.table.TableExportDescription;
import net.fichotheque.exportation.table.TableParameterDef;
import net.fichotheque.tools.exportation.table.TableDefParser;
import net.fichotheque.tools.exportation.table.TableExportContentDescriptionBuilder;
import net.fichotheque.tools.exportation.table.TableExportDescriptionBuilder;
import net.mapeadores.util.format.FormatConstants;


/**
 *
 * @author Vincent Calame
 */
public class TableExportCompiler {

    private final TableExportContext tableExportContext;

    public TableExportCompiler(TableExportContext tableExportContext) {
        this.tableExportContext = tableExportContext;
    }

    public TableExportDescription compile(TableExportStorage.Unit tableExportStorageUnit) {
        Fichotheque fichotheque = tableExportContext.getFichotheque();
        TableExportDef tableExportDef = tableExportStorageUnit.getTableExportDef();
        String state;
        List<StorageContent> storageList = tableExportStorageUnit.getStorageContentList();
        TableExportDescriptionBuilder tableExportDescriptionBuilder = new TableExportDescriptionBuilder(tableExportDef);
        if (!storageList.isEmpty()) {
            int errorCount = 0;
            boolean withMinorErrors = false;
            boolean editable = true;
            for (StorageContent storageContent : storageList) {
                String contentPath = storageContent.getPath();
                if (!contentPath.endsWith(".txt")) {
                    continue;
                }
                TableExportContentDescriptionBuilder contentBuilder = new TableExportContentDescriptionBuilder(contentPath, tableExportDef.getName());
                String contentState = TableExportContentDescription.UNKNOWN_NAME_STATE;
                boolean done = false;
                if (contentPath.equals("junction.txt")) {

                } else {
                    try {
                        SubsetKey subsetKey = SubsetKey.parse(contentPath.substring(0, contentPath.length() - 4));
                        if ((subsetKey.isCorpusSubset()) || (subsetKey.isThesaurusSubset())) {
                            done = true;
                            contentBuilder.setSubsetKey(subsetKey);
                            Subset subset = fichotheque.getSubset(subsetKey);
                            if (subset == null) {
                                contentState = TableExportContentDescription.UNKNOWN_SUBSET_STATE;
                                errorCount++;
                            } else {
                                try (InputStreamReader reader = new InputStreamReader(storageContent.getInputStream(), "UTF-8")) {
                                    TableDef tableDef = TableDefParser.parse(reader, subset, tableExportContext, contentBuilder.getLineMessageHandler(), 0);
                                    contentBuilder.setTableDef(tableDef);
                                    boolean withCol = testColDef(tableDef);
                                    if (withCol) {
                                        if (contentBuilder.hasMessage()) {
                                            withMinorErrors = true;
                                            contentState = TableExportContentDescription.OK_WITH_ERRORS_STATE;
                                        } else {
                                            contentState = TableExportContentDescription.OK_STATE;
                                        }
                                    } else {
                                        errorCount++;
                                        if (contentBuilder.hasMessage()) {
                                            contentState = TableExportContentDescription.EMPTY_WITH_ERRORS_STATE;
                                        } else {
                                            contentBuilder.getLineMessageHandler().addMessage(FormatConstants.WARNING_SYNTAX, 0, "_ warning.exportation.emptycontent");
                                            contentState = TableExportContentDescription.EMPTY_STATE;
                                        }
                                    }
                                } catch (IOException ioe) {
                                    throw new BdfStorageException(ioe);
                                }
                            }
                        }
                    } catch (ParseException pe) {
                    }
                }
                if (!done) {
                    contentState = TableExportContentDescription.UNKNOWN_NAME_STATE;
                    errorCount++;
                }
                tableExportDescriptionBuilder.addTableExportContentDescription(contentBuilder
                        .setState(contentState)
                        .toTableExportContentDescription());
            }
            if ((errorCount == 0) && (!withMinorErrors)) {
                state = TableExportDescription.OK_STATE;
            } else if (errorCount == storageList.size()) {
                state = TableExportDescription.DISABLED_STATE;
            } else {
                state = TableExportDescription.CONTAINS_ERRORS_STATE;
            }
            tableExportDescriptionBuilder.setState(state);
        }
        return tableExportDescriptionBuilder.toTableExportDescription();
    }

    private static boolean testColDef(TableDef tableDef) {
        for (TableDefItem defItem : tableDef.getDefItemList()) {
            if (!(defItem instanceof TableParameterDef)) {
                return true;
            }
        }
        return false;
    }

}
