/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.returning.model;

import java.math.*;

import java.util.*;

import java.io.StringWriter;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.ReturningPolicy;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.queries.SQLCall;

// This adapter requires project of type ReturningProject");
public class AdapterForReturningProject extends AdapterWithReturnObjectControl {

    static class InsertInfo {
        InsertInfo(boolean isReadOnly, boolean isSequence, boolean overrideNullOnly, Object value) {
            this.isReadOnly = isReadOnly;
            this.isSequence = isSequence;
            this.overrideNullOnly = overrideNullOnly;
            this.value = value;
        }
        boolean isReadOnly;
        boolean isSequence;
        boolean overrideNullOnly;
        Object value;
    }

    static class UpdateInfo {
        UpdateInfo(boolean overrideNullOnly, Object value) {
            this.overrideNullOnly = overrideNullOnly;
            this.value = value;
        }
        boolean overrideNullOnly;
        Object value;
    }

    Hashtable insertInfos = new Hashtable();
    Hashtable updateInfos = new Hashtable();

    public void addInsert(String qualifiedName, Object value) {
        DatabaseField field = new DatabaseField(qualifiedName);
        field.setType(java.math.BigDecimal.class);
        insertInfos.put(field, new InsertInfo(false, false, false, value));
    }

    public void addInsert(String qualifiedName, Object value, boolean overrideNullOnly) {
        DatabaseField field = new DatabaseField(qualifiedName);
        field.setType(java.math.BigDecimal.class);
        insertInfos.put(field, new InsertInfo(false, false, overrideNullOnly, value));
    }

    public void addInsertReadOnly(String qualifiedName, Object value) {
        DatabaseField field = new DatabaseField(qualifiedName);
        field.setType(java.math.BigDecimal.class);
        insertInfos.put(field, new InsertInfo(false, false, false, value));
    }

    public void addInsertSequence(String qualifiedName) {
        DatabaseField field = new DatabaseField(qualifiedName);
        field.setType(java.math.BigDecimal.class);
        insertInfos.put(field, new InsertInfo(false, true, false, new BigDecimal(0)));
    }

    public void addInsertSequenceReadOnly(String qualifiedName) {
        DatabaseField field = new DatabaseField(qualifiedName);
        field.setType(java.math.BigDecimal.class);
        insertInfos.put(field, new InsertInfo(true, true, false, new BigDecimal(0)));
    }

    public void addUpdate(String qualifiedName, Object value) {
        DatabaseField field = new DatabaseField(qualifiedName);
        field.setType(java.math.BigDecimal.class);
        updateInfos.put(field, new UpdateInfo(false, value));
    }

    public void addUpdate(String qualifiedName, Object value, boolean overrideNullOnly) {
        DatabaseField field = new DatabaseField(qualifiedName);
        field.setType(java.math.BigDecimal.class);
        updateInfos.put(field, new UpdateInfo(overrideNullOnly, value));
    }

    @Override
    public void updateProject(Project project, Session session) {
        ClassDescriptor desc = project.getClassDescriptor(Class1.class);
        if (!desc.hasReturningPolicy()) {
            desc.setReturningPolicy(new ReturningPolicy());
        }
        Enumeration insertFields = insertInfos.keys();
        while (insertFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)insertFields.nextElement();
            InsertInfo info = (InsertInfo)insertInfos.get(field);
            if (info.isReadOnly) {
                desc.getReturningPolicy().addFieldForInsertReturnOnly(field);
            } else {
                desc.getReturningPolicy().addFieldForInsert(field);
            }
        }
        Enumeration updateFields = updateInfos.keys();
        while (updateFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)updateFields.nextElement();
            UpdateInfo info = (UpdateInfo)updateInfos.get(field);
            desc.getReturningPolicy().addFieldForUpdate(field);
        }
    }

    @Override
    public void updateDatabase(Session session) {
        createSequence(session);
        createInsertTrigger(session);
        createUpdateTriggers(session);
    }

    protected void createSequence(Session session) {
        Enumeration insertFields = insertInfos.keys();
        while (insertFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)insertFields.nextElement();
            InsertInfo info = (InsertInfo)insertInfos.get(field);
            if (info.isSequence) {
                String seqName = field.getTableName() + "_" + field.getName() + "_SEQ";
                try {
                    session.executeNonSelectingCall(new SQLCall("DROP SEQUENCE " + seqName));
                } catch (Exception e) {
                }
                session.executeNonSelectingCall(new SQLCall("CREATE SEQUENCE " + seqName));
            }
        }
    }

    protected void createInsertTrigger(Session session) {
        StringWriter writer = new StringWriter();
        writer.write("CREATE OR REPLACE TRIGGER RETURNING_TRIGGER_INS BEFORE INSERT ON RETURNING FOR EACH ROW ");
        writer.write("BEGIN\n");

        Enumeration insertFields = insertInfos.keys();
        while (insertFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)insertFields.nextElement();
            InsertInfo info = (InsertInfo)insertInfos.get(field);
            if (info.overrideNullOnly) {
                writer.write("  IF :new." + field.getName() + " IS NULL THEN\n  ");
            }
            if (info.isSequence) {
                String seqName = field.getTableName() + "_" + field.getName() + "_SEQ";
                writer.write("  SELECT " + seqName + ".NEXTVAL INTO :new." + field.getName() + " FROM DUAL;\n");
            } else {
                if (info.value == null) {
                    writer.write("  :new." + field.getName() + " := null;\n");
                } else {
                    writer.write("  :new." + field.getName() + " := " + info.value + ";\n");
                }
            }
            if (info.overrideNullOnly) {
                writer.write("  END IF;\n");
            }
        }
        writer.write("END;");
        String str = writer.toString();
        DataModifyQuery query = new DataModifyQuery(new SQLCall(str));
        query.setShouldBindAllParameters(false);
        session.executeQuery(query);
    }

    protected void createUpdateTriggers(Session session) {
        Enumeration updateFields = updateInfos.keys();
        while (updateFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)updateFields.nextElement();
            UpdateInfo info = (UpdateInfo)updateInfos.get(field);
            createUpdateTrigger(session, field, info);
        }
    }

    protected void createUpdateTrigger(Session session, DatabaseField field, UpdateInfo info) {
        StringWriter writer = new StringWriter();
        writer.write("CREATE OR REPLACE TRIGGER RETURNING_TRIGGER_UPD_" + field.getName() + "  BEFORE UPDATE OF " + field.getName() + " ON RETURNING FOR EACH ROW ");
        writer.write("BEGIN\n");

        if (info.overrideNullOnly) {
            writer.write("  IF :new." + field.getName() + " IS NULL THEN\n  ");
        }
        if (info.value == null) {
            writer.write("  :new." + field.getName() + " := null;\n");
        } else {
            writer.write("  :new." + field.getName() + " := " + info.value + ";\n");
        }
        if (info.overrideNullOnly) {
            writer.write("  END IF;\n");
        }

        writer.write("END;");
        String str = writer.toString();
        DataModifyQuery query = new DataModifyQuery(new SQLCall(str));
        query.setShouldBindAllParameters(false);
        session.executeQuery(query);
    }

    @Override
    protected org.eclipse.persistence.sessions.Record getRowForInsert(org.eclipse.persistence.sessions.Record rowToInsert) {
        org.eclipse.persistence.sessions.Record row = new DatabaseRecord();
        Enumeration insertFields = insertInfos.keys();
        while (insertFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)insertFields.nextElement();
            InsertInfo info = (InsertInfo)insertInfos.get(field);
            Object valueIn = rowToInsert.get(field);
            if (!info.overrideNullOnly || valueIn == null) {
                row.put(field, info.value);
            }
        }
        return row;
    }

    @Override
    protected org.eclipse.persistence.sessions.Record getRowForUpdate(org.eclipse.persistence.sessions.Record rowChange) {
        org.eclipse.persistence.sessions.Record row = new DatabaseRecord();
        Enumeration updateFields = updateInfos.keys();
        while (updateFields.hasMoreElements()) {
            DatabaseField field = (DatabaseField)updateFields.nextElement();
            UpdateInfo info = (UpdateInfo)updateInfos.get(field);
            if (rowChange.containsKey(field)) {
                Object valueIn = rowChange.get(field);
                if (!info.overrideNullOnly || valueIn == null) {
                    row.put(field, info.value);
                }
            }
        }
        return row;
    }
}
