/*
 * Copyright (C) 2016 Jorge Ruesga
 *
 * Licensed 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 com.ruesga.gerrit.plugins.fcm;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.h2.jdbcx.JdbcConnectionPool;
import org.h2.jdbcx.JdbcDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.ruesga.gerrit.plugins.fcm.rest.CloudNotificationInfo;

@Singleton
public class DatabaseManager {

    private static final Logger log =
            LoggerFactory.getLogger(Configuration.class);

    private static final String DATABASE_NAME = "cloud-notifications";

    private final File dbFile;
    private final String pluginName;
    private final Gson gson;
    private JdbcConnectionPool connectionPool;

    @Inject
    public DatabaseManager(
            @PluginName String pluginName,
            @PluginData java.nio.file.Path path,
            Configuration cfg) {
        this.pluginName = pluginName;
        this.gson = new GsonBuilder().create();
        if (cfg.databasePath != null && !cfg.databasePath.isEmpty()) {
            this.dbFile = new File(cfg.databasePath);
        } else {
            this.dbFile = new File(path.toFile(), DATABASE_NAME);
        }

        boolean canWrite = (this.dbFile.exists() && this.dbFile.canWrite())
                || (this.dbFile.getParentFile() != null
                && this.dbFile.getParentFile().canWrite());
        if (!canWrite) {
            log.warn(String.format(
                    "[%s] Database is not writeable.", pluginName));
            throw new IllegalArgumentException("Database is not writeable: "
                    + this.dbFile.getAbsolutePath());
        }
    }

    public void initialize() {
        log.info(String.format("[%s] Initialize database [%s]...",
                pluginName, this.dbFile.getAbsolutePath()));

        JdbcDataSource ds = new JdbcDataSource();
        ds.setURL("jdbc:h2:" + this.dbFile.getAbsolutePath());
        this.connectionPool = JdbcConnectionPool.create(ds);
        createDatabaseIfNeeded();
    }

    public void shutdown() {
        this.connectionPool.dispose();
    }

    public CloudNotificationInfo getCloudNotification(
            int accountId, String deviceId, String token) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = this.connectionPool.getConnection();
            st = conn.prepareStatement("select * from notifications where " +
                    "user = ? and device = ? and token = ?");
            st.setInt(1, accountId);
            st.setString(2, deviceId);
            st.setString(3, token);
            rs = st.executeQuery();
            if (rs.next()) {
                return gson.fromJson(
                        rs.getString("data"), CloudNotificationInfo.class);
            }
        } catch (SQLException ex) {
            log.warn(String.format(
                    "[%s] Failed to access notifications database",
                    this.pluginName), ex);
        } finally {
            safelyCloseResources(conn, st, rs);
        }

        return null;
    }

    public List<CloudNotificationInfo> getCloudNotifications(int accountId) {
        List<CloudNotificationInfo> notifications = new ArrayList<>();
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = this.connectionPool.getConnection();
            st = conn.prepareStatement("select * from notifications where " +
                    "user = ?");
            st.setInt(1, accountId);
            rs = st.executeQuery();
            while (rs.next()) {
                notifications.add(gson.fromJson(
                        rs.getString("data"), CloudNotificationInfo.class));
            }
        } catch (SQLException ex) {
            log.warn(String.format(
                    "[%s] Failed to access notifications database",
                    this.pluginName), ex);
        } finally {
            safelyCloseResources(conn, st, rs);
        }

        return notifications;
    }

    public List<CloudNotificationInfo> getCloudNotifications(
            int accountId, String device) {
        List<CloudNotificationInfo> notifications = new ArrayList<>();
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = this.connectionPool.getConnection();
            st = conn.prepareStatement("select * from notifications where " +
                    "user = ? and device = ?");
            st.setInt(1, accountId);
            st.setString(2, device);
            rs = st.executeQuery();
            while (rs.next()) {
                notifications.add(gson.fromJson(
                        rs.getString("data"), CloudNotificationInfo.class));
            }
        } catch (SQLException ex) {
            log.warn(String.format(
                    "[%s] Failed to access notifications database",
                    this.pluginName), ex);
        } finally {
            safelyCloseResources(conn, st, rs);
        }

        return notifications;
    }

    public void registerCloudNotification(
            int accountId, CloudNotificationInfo notification) {
        Connection conn = null;
        PreparedStatement st = null;
        try {
            conn = this.connectionPool.getConnection();
            st = conn.prepareStatement("merge into notifications (user, " +
                    "device, token, data) KEY(user, device, token) " +
                    "VALUES (?, ?, ?, ?)");
            st.setInt(1, accountId);
            st.setString(2, notification.device);
            st.setString(3, notification.token);
            st.setString(4, gson.toJson(notification));
            st.execute();
        } catch (SQLException ex) {
            log.warn(String.format(
                    "[%s] Failed to update device: %s",
                    this.pluginName, notification.device), ex);
        } finally {
            safelyCloseResources(conn, st, null);
        }
    }

    public void unregisterCloudNotification(
            int accountId, String deviceId, String token) {
        Connection conn = null;
        PreparedStatement st = null;
        try {
            conn = this.connectionPool.getConnection();
            st = conn.prepareStatement("delete from notifications where " +
                    "user = ? and device = ? and token = ?");
            st.setInt(1, accountId);
            st.setString(2, deviceId);
            st.setString(3, token);
            st.execute();
        } catch (SQLException ex) {
            log.warn(String.format(
                    "[%s] Failed to delete device: %s",
                    this.pluginName, deviceId), ex);
        } finally {
            safelyCloseResources(conn, st, null);
        }
    }

    private void createDatabaseIfNeeded() {
        Connection conn = null;
        Statement st = null;
        try {
            conn = this.connectionPool.getConnection();
            st = conn.createStatement();
            st.execute(
                    "create table if not exists notifications (" +
                    "user int unsigned NOT NULL, " +
                    "device varchar(250) NOT NULL, " +
                    "token varchar(250) NOT NULL, " +
                    "data varchar(4000) NOT NULL," +
                    "primary key (user, device, token))");
        } catch (SQLException ex) {
            // The table exists. Ignore
        } finally {
            safelyCloseResources(conn, st, null);
        }
    }

    private void safelyCloseResources(
            Connection conn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception ex) {
                // Ignore
            }
        }
        if (st != null) {
            try {
                st.close();
            } catch (Exception ex) {
                // Ignore
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception ex) {
                // Ignore
            }
        }
    }
}
