/*
 * The Exomiser - A tool to annotate and prioritize genomic variants
 *
 * Copyright (c) 2016-2017 Queen Mary University of London.
 * Copyright (c) 2012-2016 Charité Universitätsmedizin Berlin and Genome Research Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.monarchinitiative.exomiser.web.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 * @author Jules Jacobsen <jules.jacobsen@sanger.ac.uk>
 */
@Component
public class JdbcExomiserDao implements ExomiserDao {

    private static final Logger logger = LoggerFactory.getLogger(JdbcExomiserDao.class);

    private final DataSource dataSource;

    @Autowired
    public JdbcExomiserDao(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Map<String, String> getDiseases() {
        String query = "SELECT disease_id, diseasename FROM disease";
        try (
                Connection connection = dataSource.getConnection();
                PreparedStatement preparedStatement = createPreparedStatement(connection, query);
                ResultSet rs = preparedStatement.executeQuery()) {

            return processGetDiseasesResults(rs);

        } catch (SQLException e) {
            logger.error("Error executing getDiseases query: ", e);
        }

        return Collections.emptyMap();
    }

    @Override
    public Map<String, String> getHpoTerms() {
        String query = "select id, lcname from hpo";
        try (
                Connection connection = dataSource.getConnection();
                PreparedStatement preparedStatement = createPreparedStatement(connection, query);
                ResultSet rs = preparedStatement.executeQuery()) {

            return processGetHpoTermsResults(rs);

        } catch (SQLException e) {
            logger.error("Error executing getHpoTerms query: ", e);
        }

        return Collections.emptyMap();
    }
    
    @Override
    public Map<String, String> getGenes() {
        String query = "select human_gene_symbol, human_gene_symbol from human2mouse_orthologs";
        try (
                Connection connection = dataSource.getConnection();
                PreparedStatement preparedStatement = createPreparedStatement(connection, query);
                ResultSet rs = preparedStatement.executeQuery()) {

            return processGetHpoTermsResults(rs);

        } catch (SQLException e) {
            logger.error("Error executing getGenes query: ", e);
        }

        return Collections.emptyMap();
    }

    private PreparedStatement createPreparedStatement(Connection connection, String query) throws SQLException {
        PreparedStatement preparedStatement = connection.prepareStatement(query);
        return preparedStatement;
    }

    private Map<String, String> processGetDiseasesResults(ResultSet rs) throws SQLException {
        Map<String, String> diseaseIdToTerms = new ConcurrentHashMap<>();

        while (rs.next()) {
            String diseaseId = rs.getString(1);
            String diseaseTerm = (rs.getString(2) == null)? "": rs.getString(2);
            if (diseaseId != null) {
                diseaseId = diseaseId.trim();
                diseaseIdToTerms.put(diseaseId, diseaseTerm);
            }
        }

        return diseaseIdToTerms;
    }

    private Map<String, String> processGetHpoTermsResults(ResultSet rs) throws SQLException {
        Map<String, String> hpoTerms = new ConcurrentHashMap<>();

        while (rs.next()) {
            String hpId = rs.getString(1);
            String hpTerm = rs.getString(2);
            hpId = hpId.trim();
            hpoTerms.put(hpId, hpTerm);
        }
        
        return hpoTerms;
    }

}

@@ -96,10 +96,10 @@
 6-20
+2
 1
-7
  Que
@@ -1058,16 +1058,79 @@
 owired;%0A
+import org.springframework.beans.factory.annotation.Qualifier;%0A
 import o
@@ -1731,32 +1731,415 @@
 Dao(
-DataSource dataSource) %7B
+@Qualifier(%22phenotypeDataSource%22) DataSource phenotypeDataSource) %7B%0A        // n.b. Need to use the phenotypeDatasource bean as this contains the reference to the exomiser database.%0A        // This is provided via the exomiser-spring-boot-autoconfigure%0A        // Without this spring will autowire the first datasource it finds which happens to be the genomeDatasource%0A        // which has the wrong schema.
 %0A   
@@ -2161,17 +2161,26 @@
 ource = 
-d
+phenotypeD
 ataSourc

Update exomiser-web JdbcExomiserDao to use named DataSource