/*
 * DBeaver - Universal Database Manager
 * Copyright (C) 2010-2021 DBeaver Corp and others
 *
 * 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 org.jkiss.dbeaver.ext.postgresql.model.data;

import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.data.DBDFormatSettings;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.exec.DBCStatement;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
import org.jkiss.dbeaver.model.impl.jdbc.data.handlers.JDBCDateTimeValueHandler;
import org.jkiss.dbeaver.model.messages.ModelMessages;
import org.jkiss.dbeaver.model.struct.DBSTypedObject;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;

/**
 * PostgreDateTimeValueHandler.
 */
public class PostgreDateTimeValueHandler extends JDBCDateTimeValueHandler {
    private static final String POSITIVE_INFINITY_STRING_REPRESENTATION = "+Infinity";
    private static final String NEGATIVE_INFINITY_STRING_REPRESENTATION = "-Infinity";
    private static final long POSITIVE_INFINITY = 9223372036825200000L;
    private static final long NEGATIVE_INFINITY = -9223372036832400000L;

    public PostgreDateTimeValueHandler(DBDFormatSettings formatSettings) {
        super(formatSettings);
    }

    @Override
    public Object getValueFromObject(@NotNull DBCSession session, @NotNull DBSTypedObject type, Object object, boolean copy, boolean validateValue) throws DBCException {
        if (!(object instanceof Timestamp)) {
            return super.getValueFromObject(session, type, object, copy, validateValue);
        }
        Timestamp timestamp = (Timestamp) object;
        long time = timestamp.getTime();
        if (time == POSITIVE_INFINITY) {
            return POSITIVE_INFINITY_STRING_REPRESENTATION;
        }
        if (time == NEGATIVE_INFINITY) {
            return NEGATIVE_INFINITY_STRING_REPRESENTATION;
        }
        return super.getValueFromObject(session, type, object, copy, validateValue);
    }

    @Override
    public void bindValueObject(@NotNull DBCSession session, @NotNull DBCStatement statement, @NotNull DBSTypedObject type, int index, Object value) throws DBCException {
        if (value instanceof String) {
            try {
                ((JDBCPreparedStatement)statement).setObject(index + 1, value.toString(), Types.OTHER);
            }
            catch (SQLException e) {
                throw new DBCException(ModelMessages.model_jdbc_exception_could_not_bind_statement_parameter, e);
            }
            return;
        }
        super.bindValueObject(session, statement, type, index, value);
    }
}
@@ -1468,10 +1468,9 @@
  = %22
-+I
+i
 nfin
@@ -1551,17 +1551,17 @@
 ION = %22-
-I
+i
 nfinity%22
@@ -1553,32 +1553,113 @@
 N = %22-infinity%22;
+%0A%0A    // https://jdbc.postgresql.org/documentation/publicapi/constant-values.html
 %0A    private sta
@@ -1673,20 +1673,20 @@
 al long 
-POSI
+NEGA
 TIVE_INF
@@ -1693,16 +1693,17 @@
 INITY = 
+-
 92233720
@@ -1709,11 +1709,11 @@
 0368
-252
+324
 0000
@@ -1747,32 +1747,40 @@
 l long NEGATIVE_
+SMALLER_
 INFINITY = -9223
@@ -1771,38 +1771,188 @@
 INFINITY = -
-92233720368324
+185543533774800000L;%0A    private static final long POSITIVE_INFINITY = 9223372036825200000L;%0A    private static final long POSITIVE_SMALLER_INFINITY = 1855435337748
 00000L;%0A%0A   
@@ -2402,30 +2402,27 @@
     
-Timestamp timestamp
+final long time
  = 
+(
 (Tim
@@ -2439,39 +2439,9 @@
 ject
-;%0A        long time = timestamp
+)
 .get
@@ -2468,24 +2468,61 @@
 time == 
-POSITIVE
+NEGATIVE_INFINITY %7C%7C time == NEGATIVE_SMALLER
 _INFINIT
@@ -2612,32 +2612,69 @@
 if (time == 
-NEGATIVE
+POSITIVE_INFINITY %7C%7C time == POSITIVE_SMALLER
 _INFINITY) %7B

#12639 Fix positive infinity representation for date/time