/* FichothequeLib_Tools - Copyright (c) 2011-2024 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 net.fichotheque.tools.exportation.sql;

import java.text.ParseException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.RandomAccess;
import net.fichotheque.exportation.sql.SqlExportDef;
import net.fichotheque.selection.SelectionOptions;
import net.fichotheque.tools.selection.SelectionOptionsBuilder;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.misc.DefBuilder;
import net.mapeadores.util.text.Labels;
import net.mapeadores.util.text.RelativePath;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public class SqlExportDefBuilder extends DefBuilder {

    private final String name;
    private final SelectionOptionsBuilder selectionOptionsBuilder = new SelectionOptionsBuilder();
    private final List<InternalParam> paramList = new ArrayList<InternalParam>();
    private String sqlExportClassName = "";
    private String tableExportName = "";
    private String postCommand = "";
    private String targetName = "";
    private RelativePath targetPath = RelativePath.EMPTY;
    private String fileName = "";
    private String selectionDefName = "";

    public SqlExportDefBuilder(String name) {
        this(name, null);
    }

    public SqlExportDefBuilder(String name, Attributes initAttributes) {
        super(initAttributes);
        try {
            SqlExportDef.checkSqlExportName(name);
        } catch (ParseException pe) {
            throw new IllegalArgumentException("Wrong name: " + name);
        }
        this.name = name;
    }

    public SelectionOptionsBuilder getSelectionOptionsBuilder() {
        return selectionOptionsBuilder;
    }

    public SqlExportDefBuilder setSqlExportClassName(String sqlExportClassName) {
        this.sqlExportClassName = StringUtils.nullTrim(sqlExportClassName);
        return this;
    }

    public SqlExportDefBuilder setTableExportName(String tableExportName) {
        this.tableExportName = StringUtils.nullTrim(tableExportName);
        return this;
    }

    public SqlExportDefBuilder setPostCommand(String postCommand) {
        this.postCommand = StringUtils.nullTrim(postCommand);
        return this;
    }

    public SqlExportDefBuilder addParam(String name, String value) {
        name = StringUtils.nullTrim(name);
        if (name.isEmpty()) {
            throw new IllegalArgumentException("name is null or empty");
        }
        value = StringUtils.nullTrim(value);
        paramList.add(new InternalParam(name, value));
        return this;
    }

    public SqlExportDefBuilder setTargetName(String targetName) {
        this.targetName = StringUtils.nullTrim(targetName);
        return this;
    }

    public SqlExportDefBuilder setTargetPath(RelativePath targetPath) {
        if (targetPath == null) {
            targetPath = RelativePath.EMPTY;
        }
        this.targetPath = targetPath;
        return this;
    }

    public SqlExportDefBuilder setFileName(String fileName) throws ParseException {
        fileName = StringUtils.nullTrim(fileName);
        if (!fileName.isEmpty()) {
            RelativePath relativePath = RelativePath.parse(fileName);
            fileName = relativePath.getLastName();
        }
        this.fileName = fileName;
        return this;
    }

    public SqlExportDefBuilder setSelectionDefName(String selectionDefName) {
        this.selectionDefName = StringUtils.nullTrim(selectionDefName);
        return this;
    }

    public SqlExportDef toSqlExportDef() {
        List<SqlExportDef.Param> immutableParamList = new ParamList(paramList.toArray(new InternalParam[paramList.size()]));
        Labels titleLabels = toLabels();
        Attributes attributes = toAttributes();
        return new InternalSqlExportDef(name, sqlExportClassName, tableExportName, postCommand, immutableParamList, selectionOptionsBuilder.toSelectionOptions(), targetName, targetPath, fileName, titleLabels, attributes);
    }

    public static SqlExportDefBuilder init(String name) {
        return new SqlExportDefBuilder(name);
    }

    public static SqlExportDefBuilder init(String name, Attributes initAttributes) {
        return new SqlExportDefBuilder(name, initAttributes);
    }


    private static class InternalSqlExportDef implements SqlExportDef {

        private final String name;
        private final String sqlExportClassName;
        private final String tableExportName;
        private final String postCommand;
        private final List<SqlExportDef.Param> paramList;
        private final SelectionOptions selectionOptions;
        private final String targetName;
        private final RelativePath targetPath;
        private final String fileName;
        private final Labels titleLabels;
        private final Attributes attributes;

        private InternalSqlExportDef(String name, String sqlExportClassName, String tableExportName, String postCommand, List<SqlExportDef.Param> paramList, SelectionOptions selectionOptions, String targetName, RelativePath targetPath, String fileName,
                Labels titleLabels, Attributes attributes) {
            this.name = name;
            this.sqlExportClassName = sqlExportClassName;
            this.tableExportName = tableExportName;
            this.postCommand = postCommand;
            this.paramList = paramList;
            this.selectionOptions = selectionOptions;
            this.targetName = targetName;
            this.targetPath = targetPath;
            this.fileName = fileName;
            this.titleLabels = titleLabels;
            this.attributes = attributes;
        }

        @Override
        public String getSqlExportClassName() {
            return sqlExportClassName;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public Labels getTitleLabels() {
            return titleLabels;
        }

        @Override
        public Attributes getAttributes() {
            return attributes;
        }

        @Override
        public String getTableExportName() {
            return tableExportName;
        }

        @Override
        public String getPostCommand() {
            return postCommand;
        }

        @Override
        public List<SqlExportDef.Param> getParamList() {
            return paramList;
        }

        @Override
        public SelectionOptions getSelectionOptions() {
            return selectionOptions;
        }

        @Override
        public String getTargetName() {
            return targetName;
        }

        @Override
        public RelativePath getTargetPath() {
            return targetPath;
        }

        @Override
        public String getFileName() {
            return fileName;
        }

    }


    private static class InternalParam implements SqlExportDef.Param {

        private final String name;
        private final String value;

        private InternalParam(String name, String value) {
            this.name = name;
            this.value = value;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public String getValue() {
            return value;
        }

    }


    private static class ParamList extends AbstractList<SqlExportDef.Param> implements RandomAccess {

        private final SqlExportDef.Param[] array;

        private ParamList(SqlExportDef.Param[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public SqlExportDef.Param get(int index) {
            return array[index];
        }

    }

}
