/**
 * 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.fineract.notification.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.service.Page;
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
import org.apache.fineract.notification.cache.CacheNotificationResponseHeader;
import org.apache.fineract.notification.data.NotificationData;
import org.apache.fineract.notification.data.NotificationMapperData;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

@RequiredArgsConstructor
public class NotificationReadPlatformServiceImpl implements NotificationReadPlatformService {

    private HashMap<Long, HashMap<Long, CacheNotificationResponseHeader>> tenantNotificationResponseHeaderCache = new HashMap<>();

    private final NotificationDataRow notificationDataRow = new NotificationDataRow();
    private final NotificationMapperRow notificationMapperRow = new NotificationMapperRow();

    private final JdbcTemplate jdbcTemplate;
    private final PlatformSecurityContext context;
    private final ColumnValidator columnValidator;
    private final PaginationHelper paginationHelper;
    private final DatabaseSpecificSQLGenerator sqlGenerator;

    @Override
    public boolean hasUnreadNotifications(Long appUserId) {
        Long tenantId = ThreadLocalContextUtil.getTenant().getId();
        Long now = System.currentTimeMillis() / 1000L;
        if (this.tenantNotificationResponseHeaderCache.containsKey(tenantId)) {
            HashMap<Long, CacheNotificationResponseHeader> notificationResponseHeaderCache = this.tenantNotificationResponseHeaderCache
                    .get(tenantId);
            if (notificationResponseHeaderCache.containsKey(appUserId)) {
                Long lastFetch = notificationResponseHeaderCache.get(appUserId).getLastFetch();
                if ((now - lastFetch) > 1) {
                    return this.createUpdateCacheValue(appUserId, now, notificationResponseHeaderCache);
                } else {
                    return notificationResponseHeaderCache.get(appUserId).hasNotifications();
                }
            } else {
                return this.createUpdateCacheValue(appUserId, now, notificationResponseHeaderCache);
            }
        } else {
            return this.initializeTenantNotificationResponseHeaderCache(tenantId, now, appUserId);

        }
    }

    private boolean initializeTenantNotificationResponseHeaderCache(Long tenantId, Long now, Long appUserId) {
        HashMap<Long, CacheNotificationResponseHeader> notificationResponseHeaderCache = new HashMap<>();
        this.tenantNotificationResponseHeaderCache.put(tenantId, notificationResponseHeaderCache);
        return this.createUpdateCacheValue(appUserId, now, notificationResponseHeaderCache);
    }

    private boolean createUpdateCacheValue(Long appUserId, Long now,
            HashMap<Long, CacheNotificationResponseHeader> notificationResponseHeaderCache) {
        boolean hasNotifications;
        Long tenantId = ThreadLocalContextUtil.getTenant().getId();
        CacheNotificationResponseHeader cacheNotificationResponseHeader;
        hasNotifications = checkForUnreadNotifications(appUserId);
        cacheNotificationResponseHeader = new CacheNotificationResponseHeader(hasNotifications, now);
        notificationResponseHeaderCache.put(appUserId, cacheNotificationResponseHeader);
        this.tenantNotificationResponseHeaderCache.put(tenantId, notificationResponseHeaderCache);
        return hasNotifications;
    }

    private boolean checkForUnreadNotifications(Long appUserId) {
        String sql = "SELECT id, notification_id as notificationId, user_id as userId, is_read as isRead, created_at "
                + "as createdAt FROM notification_mapper WHERE user_id = ? AND is_read = false";
        List<NotificationMapperData> notificationMappers = this.jdbcTemplate.query(sql, notificationMapperRow, appUserId);
        return notificationMappers.size() > 0;
    }

    @Override
    public void updateNotificationReadStatus() {
        final Long appUserId = context.authenticatedUser().getId();
        String sql = "UPDATE notification_mapper SET is_read = true WHERE is_read = false and user_id = ?";
        this.jdbcTemplate.update(sql, appUserId);
    }

    @Override
    public Page<NotificationData> getAllUnreadNotifications(final SearchParameters searchParameters) {
        final Long appUserId = context.authenticatedUser().getId();
        String sql = "SELECT " + sqlGenerator.calcFoundRows() + " ng.id as id, nm.user_id as userId, ng.object_type as objectType, "
                + "ng.object_identifier as objectId, ng.actor as actor, ng." + sqlGenerator.escape("action")
                + " as action, ng.notification_content "
                + "as content, ng.is_system_generated as isSystemGenerated, nm.created_at as createdAt "
                + "FROM notification_mapper nm INNER JOIN notification_generator ng ON nm.notification_id = ng.id "
                + "WHERE nm.user_id = ? AND nm.is_read = false order by nm.created_at desc";

        return getNotificationDataPage(searchParameters, appUserId, sql);
    }

    @Override
    public Page<NotificationData> getAllNotifications(SearchParameters searchParameters) {
        final Long appUserId = context.authenticatedUser().getId();
        String sql = "SELECT " + sqlGenerator.calcFoundRows() + " ng.id as id, nm.user_id as userId, ng.object_type as objectType, "
                + "ng.object_identifier as objectId, ng.actor as actor, ng." + sqlGenerator.escape("action")
                + " as action, ng.notification_content "
                + "as content, ng.is_system_generated as isSystemGenerated, nm.created_at as createdAt "
                + "FROM notification_mapper nm INNER JOIN notification_generator ng ON nm.notification_id = ng.id "
                + "WHERE nm.user_id = ? order by nm.created_at desc";

        return getNotificationDataPage(searchParameters, appUserId, sql);
    }

    private Page<NotificationData> getNotificationDataPage(SearchParameters searchParameters, Long appUserId, String sql) {
        final StringBuilder sqlBuilder = new StringBuilder(200);
        sqlBuilder.append(sql);

        if (searchParameters.hasOrderBy()) {
            sqlBuilder.append(" order by ").append(searchParameters.getOrderBy());
            this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getOrderBy());
            if (searchParameters.hasSortOrder()) {
                sqlBuilder.append(' ').append(searchParameters.getSortOrder());
                this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getSortOrder());
            }
        }

        if (searchParameters.hasLimit()) {
            sqlBuilder.append(" ");
            if (searchParameters.hasOffset()) {
                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
            } else {
                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
            }
        }

        Object[] params = new Object[] { appUserId };
        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), params, this.notificationDataRow);
    }

    private static final class NotificationMapperRow implements RowMapper<NotificationMapperData> {

        @Override
        public NotificationMapperData mapRow(ResultSet rs, int rowNum) throws SQLException {
            NotificationMapperData notificationMapperData = new NotificationMapperData();

            final Long id = rs.getLong("id");
            notificationMapperData.setId(id);

            final Long notificationId = rs.getLong("notificationId");
            notificationMapperData.setNotificationId(notificationId);

            final Long userId = rs.getLong("userId");
            notificationMapperData.setUserId(userId);

            final boolean isRead = rs.getBoolean("isRead");
            notificationMapperData.setRead(isRead);

            final String createdAt = rs.getString("createdAt");
            notificationMapperData.setCreatedAt(createdAt);

            return notificationMapperData;
        }
    }

    private static final class NotificationDataRow implements RowMapper<NotificationData> {

        @Override
        public NotificationData mapRow(ResultSet rs, int rowNum) throws SQLException {
            NotificationData notificationData = new NotificationData();

            final Long id = rs.getLong("id");
            notificationData.setId(id);

            final String objectType = rs.getString("objectType");
            notificationData.setObjectType(objectType);

            final Long objectId = rs.getLong("objectId");
            notificationData.setObjectId(objectId);

            final Long actorId = rs.getLong("actor");
            notificationData.setActorId(actorId);

            final String action = rs.getString("action");
            notificationData.setAction(action);

            final String content = rs.getString("content");
            notificationData.setContent(content);

            final boolean isSystemGenerated = rs.getBoolean("isSystemGenerated");
            notificationData.setSystemGenerated(isSystemGenerated);

            final String createdAt = rs.getString("createdAt");
            notificationData.setCreatedAt(createdAt);

            return notificationData;
        }
    }
}
