/**
 * 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.netbeans.modules.db.metadata.model.jdbc;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.modules.db.metadata.model.MetadataAccessor;
import org.netbeans.modules.db.metadata.model.MetadataUtilities;
import org.netbeans.modules.db.metadata.model.api.Catalog;
import org.netbeans.modules.db.metadata.model.api.MetadataException;
import org.netbeans.modules.db.metadata.model.api.Schema;
import org.netbeans.modules.db.metadata.model.spi.MetadataImplementation;

/**
 *
 * @author Andrei Badea
 */
public class JDBCMetadata extends MetadataImplementation {

    private static final Logger LOGGER = Logger.getLogger(JDBCMetadata.class.getName());
    private final Connection conn;
    private final String defaultSchemaName;
    private final DatabaseMetaData dmd;
    protected Catalog defaultCatalog;
    protected Map<String, Catalog> catalogs;

    public JDBCMetadata(Connection conn, String defaultSchemaName) {
        LOGGER.log(Level.FINE, "Creating metadata for default schema ''{0}''", defaultSchemaName);
        this.conn = conn;
        this.defaultSchemaName = defaultSchemaName;
        try {
            dmd = conn.getMetaData();
        } catch (SQLException e) {
            throw new MetadataException(e);
        }
        if (LOGGER.isLoggable(Level.FINE)) {
            try {
                LOGGER.log(Level.FINE, "Retrieved DMD for product ''{0}'' version ''{1}'', driver ''{2}'' version ''{3}''", new Object[]{
                            dmd.getDatabaseProductName(),
                            dmd.getDatabaseProductVersion(),
                            dmd.getDriverName(),
                            dmd.getDriverVersion()
                        });
            } catch (SQLException e) {
                LOGGER.log(Level.FINE, "Exception while logging metadata information", e);
            }
        }
    }

    @Override
    public final Catalog getDefaultCatalog() {
        initCatalogs();
        return defaultCatalog;
    }

    @Override
    public final Collection<Catalog> getCatalogs() {
        return initCatalogs().values();
    }

    @Override
    public final Catalog getCatalog(String name) {
        Catalog catalog = MetadataUtilities.find(name, initCatalogs());
        if (catalog == null && name == null) {
            return getDefaultCatalog();
        }

        return catalog;
    }

    @Override
    public Schema getDefaultSchema() {
        Catalog catalog = getDefaultCatalog();
        if (catalog != null) {
            return ((JDBCCatalog) MetadataAccessor.getDefault().getCatalogImpl(catalog)).getDefaultSchema();
        }
        return null;
    }

    @Override
    public final void refresh() {
        LOGGER.fine("Refreshing metadata");
        defaultCatalog = null;
        catalogs = null;
    }

    @Override
    public String toString() {
        return "JDBCMetadata"; // NOI18N
    }

    protected JDBCCatalog createJDBCCatalog(String name, boolean _default, String defaultSchemaName) {
        return new JDBCCatalog(this, name, _default, defaultSchemaName);
    }

    protected void createCatalogs() {
        Map<String, Catalog> newCatalogs = new LinkedHashMap<String, Catalog>();
        try {
            if (!driverReportsBogusCatalogNames()) {
                String defaultCatalogName = conn.getCatalog();
                ResultSet rs = dmd.getCatalogs();
                try {
                    while (rs.next()) {
                        String catalogName = MetadataUtilities.trimmed(rs.getString("TABLE_CAT")); // NOI18N
                        LOGGER.log(Level.FINE, "Read catalog ''{0}''", catalogName); //NOI18N
                        if (MetadataUtilities.equals(catalogName, defaultCatalogName)) {
                            defaultCatalog = createJDBCCatalog(catalogName, true, defaultSchemaName).getCatalog();
                            newCatalogs.put(defaultCatalog.getName(), defaultCatalog);
                            LOGGER.log(Level.FINE, "Created default catalog {0}", defaultCatalog); //NOI18N
                        } else {
                            Catalog catalog = createJDBCCatalog(catalogName, false, null).getCatalog();
                            newCatalogs.put(catalogName, catalog);
                            LOGGER.log(Level.FINE, "Created catalog {0}", catalog); //NOI18N
                        }
                    }
                } finally {
                    if (rs != null) {
                        rs.close();
                    }
                }
            }
        } catch (SQLException e) {
            LOGGER.log(Level.INFO, "Could not load catalogs list from database (getCatalogs failed).");
        }
        if (defaultCatalog == null) {
            defaultCatalog = createJDBCCatalog(null, true, defaultSchemaName).getCatalog();

            // Issue 154407 - Don't put the default catalog in the list of catalogs if its name is null,
            // unless it's the *only* catalog (e.g. with Derby, where it doesn't have a concept of catalogs)
            if (newCatalogs.isEmpty()) {
                newCatalogs.put(null, defaultCatalog);
            }

            LOGGER.log(Level.FINE, "Created fallback default catalog {0}", defaultCatalog);
        }
        catalogs = Collections.unmodifiableMap(newCatalogs);
    }

    private Map<String, Catalog> initCatalogs() {
        if (catalogs != null) {
            return catalogs;
        }
        LOGGER.fine("Initializing catalogs");
        createCatalogs();
        return catalogs;
    }

    public final Connection getConnection() {
        return conn;
    }

    public final DatabaseMetaData getDmd() {
        return dmd;
    }

    /**
     * Ignore reported catalogs from driver.
     *
     * Seems some drivers (aka the Pointbase jdbc driver) don't support catalogs
     * but against all assumptions report catalog names for getCatalogs(). These
     * names are bogus and need to be ignored.
     *
     * @return
     */
    private boolean driverReportsBogusCatalogNames() throws SQLException {
        String driverName = dmd.getDriverName();
        return "PointBase JDBC Driver".equals(driverName) ||
               "IBM Data Server Driver for JDBC and SQLJ".equals(driverName);
    }
}
