/*
 * 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.apache.geode.connectors.jdbc.internal;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.sql.DataSource;

import org.apache.logging.log4j.Logger;

import org.apache.geode.annotations.Experimental;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
import org.apache.geode.connectors.jdbc.JdbcConnectorException;
import org.apache.geode.connectors.jdbc.JdbcWriter;
import org.apache.geode.connectors.jdbc.internal.configuration.FieldMapping;
import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
import org.apache.geode.internal.cache.CacheService;
import org.apache.geode.internal.jndi.JNDIInvoker;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.management.internal.beans.CacheServiceMBeanBase;

@Experimental
public class JdbcConnectorServiceImpl implements JdbcConnectorService {

  private static final Logger logger = LogService.getLogger();
  private final Map<String, RegionMapping> mappingsByRegion =
      new ConcurrentHashMap<>();

  @Override
  public Set<RegionMapping> getRegionMappings() {
    Set<RegionMapping> regionMappings = new HashSet<>();
    regionMappings.addAll(mappingsByRegion.values());
    return regionMappings;
  }

  @Override
  public void createRegionMapping(RegionMapping mapping)
      throws RegionMappingExistsException {
    RegionMapping existing =
        mappingsByRegion.putIfAbsent(mapping.getRegionName(), mapping);
    if (existing != null) {
      throw new RegionMappingExistsException(
          "JDBC mapping for region " + mapping.getRegionName() + " exists");
    }
  }

  @Override
  public void replaceRegionMapping(RegionMapping alteredMapping)
      throws RegionMappingNotFoundException {
    RegionMapping existingMapping =
        mappingsByRegion.get(alteredMapping.getRegionName());
    if (existingMapping == null) {
      throw new RegionMappingNotFoundException(
          "JDBC mapping for the region " + alteredMapping.getRegionName() + " was not found");
    }

    mappingsByRegion.put(existingMapping.getRegionName(), alteredMapping);
  }

  @Override
  public boolean isMappingSynchronous(String regionName, Cache cache) {
    Region<?, ?> region = cache.getRegion(regionName);
    if (region == null) {
      throw new IllegalStateException("Region for mapping could not be found.");
    }

    // If our region has a Jdbc Writer set as the cache writer then we know it is syncronous
    return region.getAttributes().getCacheWriter() != null
        && region.getAttributes().getCacheWriter() instanceof JdbcWriter;
  }

  @Override
  public void validateMapping(RegionMapping regionMapping) {

    DataSource dataSource = getDataSource(regionMapping.getDataSourceName());
    if (dataSource == null) {
      throw new JdbcConnectorException("No datasource \"" + regionMapping.getDataSourceName()
          + "\" found when creating mapping \"" + regionMapping.getRegionName() + "\"");
    }
    validateMapping(regionMapping, dataSource);
  }

  @Override
  public void validateMapping(RegionMapping regionMapping, DataSource dataSource) {
    TableMetaDataView metaDataView = getTableMetaDataView(regionMapping, dataSource);
    boolean foundDifference = false;

    if (regionMapping.getFieldMappings().size() != metaDataView.getColumnNames().size()) {
      foundDifference = true;
    } else {
      for (FieldMapping fieldMapping : regionMapping.getFieldMappings()) {
        String jdbcName = fieldMapping.getJdbcName();
        if (!metaDataView.getColumnNames().contains(jdbcName)) {
          foundDifference = true;
          break;
        }
        if (!metaDataView.getColumnDataType(jdbcName).getName()
            .equals(fieldMapping.getJdbcType())) {
          foundDifference = true;
          break;
        }
        if (metaDataView.isColumnNullable(jdbcName) != fieldMapping.isJdbcNullable()) {
          foundDifference = true;
          break;
        }
      }
    }

    if (!foundDifference) {
      if (!regionMapping.getSpecifiedIds()
          && !regionMapping.getIds().equals(String.join(",", metaDataView.getKeyColumnNames()))) {
        foundDifference = true;
      }
    }

    if (foundDifference) {
      StringBuilder sb = new StringBuilder();
      sb.append(
          "Error detected when comparing mapping for region \"" + regionMapping.getRegionName()
              + "\" with table definition: \n");

      if (!regionMapping.getSpecifiedIds()) {
        sb.append("\nId fields in Field Mappings: " + regionMapping.getIds());
        sb.append(
            "\nId fields in Table MetaData: " + String.join(",", metaDataView.getKeyColumnNames()));
      }

      sb.append("\n\nDefinition from Field Mappings (" + regionMapping.getFieldMappings().size()
          + " field mappings found):");

      for (FieldMapping fieldMapping : regionMapping.getFieldMappings()) {
        sb.append("\n" + fieldMapping.getJdbcName() + " - " + fieldMapping.getJdbcType());
      }

      sb.append("\n\nDefinition from Table Metadata (" + metaDataView.getColumnNames().size()
          + " columns found):");

      for (String name : metaDataView.getColumnNames()) {
        sb.append("\n" + name + " - " + metaDataView.getColumnDataType(name));
      }

      sb.append("\n\nDestroy and recreate the JDBC mapping for \"" + regionMapping.getRegionName()
          + "\" to resolve this error.");

      logger.error(sb.toString());

      throw new JdbcConnectorException("Jdbc mapping for \"" + regionMapping.getRegionName()
          + "\" does not match table definition, check logs for more details.");
    }
  }


  @Override
  public RegionMapping getMappingForRegion(String regionName) {
    return mappingsByRegion.get(regionName);
  }

  @Override
  public void destroyRegionMapping(String regionName) {
    mappingsByRegion.remove(regionName);
  }

  @Override
  public void init(Cache cache) {}


  @Override
  public Class<? extends CacheService> getInterface() {
    return JdbcConnectorService.class;
  }

  @Override
  public CacheServiceMBeanBase getMBean() {
    return null;
  }


  // The following helper method is to allow for proper mocking in unit tests
  DataSource getDataSource(String dataSourceName) {
    return JNDIInvoker.getDataSource(dataSourceName);
  }

  // The following helper method is to allow for proper mocking in unit tests
  TableMetaDataManager getTableMetaDataManager() {
    return new TableMetaDataManager();
  }

  private TableMetaDataView getTableMetaDataView(RegionMapping regionMapping,
      DataSource dataSource) {
    TableMetaDataManager manager = getTableMetaDataManager();
    try (Connection connection = dataSource.getConnection()) {
      return manager.getTableMetaDataView(connection, regionMapping);
    } catch (SQLException ex) {
      throw JdbcConnectorException
          .createException("Exception thrown while connecting to datasource \""
              + regionMapping.getDataSourceName() + "\": ", ex);
    }
  }
}
