/**
 * Copyright © 2012-2025 by Data Virtuality GmbH
 */
package org.teiid.translator.jdbc;

import com.datavirtuality.dv.core.interfaces.DVCaller;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.jdbc.plugin.JDBCPlugin;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * @author Allan Vital
 * @date 2025.05.14
 */
public class FullQualifiedParserFilter {

    private String catalog;
    private String schemaPattern;
    private String tableNamePattern;
    private boolean isProcessableFilter = true;

    public FullQualifiedParserFilter(String defaultCatalog, String schemaPattern, String tableNamePattern) throws TranslatorException {
        this.schemaPattern = schemaPattern;
        this.catalog = defaultCatalog;
        this.tableNamePattern = tableNamePattern;
        processPatterns();
    }

    public String getInnerCatalog() {
        return this.catalog;
    }

    public String getInnerSchemaPattern() {
        return this.schemaPattern;
    }

    public String getInnerTableNamePattern() {
        return this.tableNamePattern;
    }

    private void processPatterns() throws TranslatorException {
        SchemaPatternFilter schemaPatternFilter = new SchemaPatternFilter(this.schemaPattern);
        TableNameFilter tableNameFilter = new TableNameFilter(this.tableNamePattern);
        try {
            consolidateCatalog(catalog, schemaPatternFilter.catalog, tableNameFilter.catalog);
            consolidateSchema(schemaPatternFilter.schema, tableNameFilter.schema);
            this.tableNamePattern = tableNameFilter.tableName;
        } catch (IllegalArgumentException e) {
            isProcessableFilter = false;
        }
    }

    private void consolidateCatalog(String catalog, String schemaCatalog, String tableCatalog) throws TranslatorException {
        validateCatalog(schemaCatalog, "schemaPattern", schemaPattern);
        validateCatalog(tableCatalog, "tableNamePattern", tableNamePattern);
        String finalCatalog = validateMatchAndGetMostSpecificOne(catalog, schemaCatalog);
        finalCatalog = validateMatchAndGetMostSpecificOne(finalCatalog, tableCatalog);
        this.catalog = finalCatalog;
    }

    private void consolidateSchema(String schema, String tableSchema) {
        this.schemaPattern = validateMatchAndGetMostSpecificOne(schema, tableSchema);
    }

    private String validateMatchAndGetMostSpecificOne(String first, String second) throws IllegalArgumentException {
        if (first == null && second == null) {
            return null;
        }
        if (Objects.equals(first, second)) {
            return first;
        }
        if (second == null) {
            return first;
        }
        if (first == null) {
            return second;
        }

        boolean firstMatchesSecond  = (Boolean) DVCaller.call(234, first, second);
        boolean secondMatchesFirst  = (Boolean) DVCaller.call(234, second, first);

        if (!firstMatchesSecond  && !secondMatchesFirst ) {
            throw new IllegalArgumentException(JDBCPlugin.Util.gs(JDBCPlugin.Event.DVCORE89150));
        }

        return firstMatchesSecond  ? first : second;
    }

    private void validateCatalog(String catalog, String origin, String originalParameter) throws TranslatorException {
        if (catalog != null && catalog.contains("%")) {
            throw new TranslatorException(JDBCPlugin.Util.gs(JDBCPlugin.Event.DVCORE89161, origin, originalParameter));
        }
    }

    private List<String> getParts(String parameter) {
        List<String> parts = (List<String>) DVCaller.call(274, parameter);
        if (parts == null) {
            return new LinkedList<>();
        }
        return parts;
    }

    public boolean isProcessableFilter() {
        return isProcessableFilter;
    }

    class SchemaPatternFilter {

        private String catalog = null;
        private String schema = null;

        public SchemaPatternFilter(String schemaPattern) {
            List<String> parts = getParts(schemaPattern);
            if (parts.size() == 2) {
                catalog = parts.get(0);
                schema = parts.get(1);
            } else {
                schema = schemaPattern;
            }
        }

    }

    class TableNameFilter {

        private String catalog = null;
        private String schema = null;
        private String tableName = null;

        public TableNameFilter(String tableNamePattern) {
            List<String> parts = getParts(tableNamePattern);
            if (parts.size() == 2) {
                this.schema = parts.get(0);
                this.tableName = parts.get(1);
            } else if (parts.size() == 3) {
                this.catalog = parts.get(0);
                this.schema = parts.get(1);
                this.tableName = parts.get(2);
            } else {
                tableName = tableNamePattern;
            }
        }

    }

    public String toString() {
        return "[" +
                "importer.catalog : " + catalog +
                ", schemaPattern : " + schemaPattern +
                ", tableNamePattern : " + tableNamePattern +
                "]";
    }

}