/*
 * 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.internal.expressions;

import java.io.*;
import java.math.*;
import java.util.Calendar;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.ConversionManager;

/**
 * <p><b>Purpose</b>: Expression Java printer.
 * <p><b>Responsibilities</b>:<ul>
 * <li> Print an expression in Java format.
 * <li> Used in project class generation.
 * </ul>
 *    @since TOPLink10.1.3
 */
public class ExpressionJavaPrinter {

    // What we write on
    protected StringWriter writer;

    // ExpressionBuilder string, e.g. expBuilder
    protected String builderString;

    // Database platform for the project
    protected DatabasePlatform platform;

    public ExpressionJavaPrinter(String builderString, StringWriter writer, DatabasePlatform platform) {
        this.builderString = builderString;
        this.writer = writer;
        this.platform = platform;
    }

    public String getBuilderString() {
        return builderString;
    }

    public DatabasePlatform getPlatform() {
        return platform;
    }

    public StringWriter getWriter() {
        return writer;
    }

    public void printString(String value) {
        getWriter().write(value);
   }

    //Used to convert a java object to java print format
    public void printJava(Object object) {
        if (object == null) {
            printString("null");
        } else if (object.getClass() == ClassConstants.STRING) {
            printString("\"");
            printString((String)object);
            printString("\"");
        } else if (object instanceof Calendar) {
            printString("new java.util.Date(");
            printString(String.valueOf(((Calendar)object).getTimeInMillis()));
            printString("L)");
        } else if (object.getClass() == ClassConstants.TIMESTAMP) {
            printString("new java.sql.Timestamp(");
            printString(String.valueOf(((java.sql.Timestamp)object).getTime()));
            printString("L)");
        } else if (object.getClass() == ClassConstants.SQLDATE) {
            printString("new java.sql.Date(");
            printString(String.valueOf(((java.sql.Date)object).getTime()));
            printString("L)");
        } else if (object.getClass() == ClassConstants.TIME) {
            printString("new java.sql.Time(");
            printString(String.valueOf(((java.sql.Time)object).getTime()));
            printString("L)");
        } else if (object.getClass() == ClassConstants.UTILDATE) {
            printString("new java.util.Date(");
            printString(String.valueOf(((java.util.Date)object).getTime()));
            printString("L)");
        } else if (object.getClass() == ClassConstants.BYTE) {
            printByte((Byte)object);
        } else if (object.getClass() == ClassConstants.APBYTE) {
            printString("new byte[] {");
            byte[] bytes = (byte[])object;
            if (bytes.length > 0) {
                printString(String.valueOf(bytes[0]));
                for (int index = 1; index < bytes.length; index++) {
                    printString(",");
                    printString(String.valueOf(bytes[index]));
                }
            }
            printString("}");
        } else if (object.getClass() == ClassConstants.ABYTE) {
            printString("new Byte[] {");
            Byte[] bytes = (Byte[])object;
            if (bytes.length > 0) {
                printByte(bytes[0]);
                for (int index = 1; index < bytes.length; index++) {
                    printString(",");
                    printByte(bytes[index]);
                }
            }
            printString("}");
        } else if (object.getClass() == ClassConstants.CHAR) {
            printCharacter((Character)object);
        } else if (object.getClass() == ClassConstants.APCHAR) {
            printString("new char[] {");
            char[] chars = (char[])object;
            if (chars.length > 0) {
                printString("'");
                printString(String.valueOf(chars[0]));
                printString("'");
                for (int index = 1; index < chars.length; index++) {
                    printString(",");
                    printString("'");
                    printString(String.valueOf(chars[index]));
                    printString("'");
                }
            }
            printString("}");
        } else if (object.getClass() == ClassConstants.ACHAR) {
            printString("new Character[] {");
            Character[] chars = (Character[])object;
            if (chars.length > 0) {
                printCharacter(chars[0]);
                for (int index = 1; index < chars.length; index++) {
                    printString(",");
                    printCharacter(chars[index]);
                }
            }
            printString("}");
        } else if (object.getClass() == ClassConstants.BIGDECIMAL) {
            printString("new java.math.BigDecimal(\"");
            printString(object.toString());
            printString("\")");
        } else if (object.getClass() == ClassConstants.BIGINTEGER) {
            printString("new java.math.BigInteger(\"");
            printString(object.toString());
            printString("\")");
        } else {
            printString(ConversionManager.getDefaultManager().convertObject(object, String.class));
        }

    }

    public void printByte(Byte aByte) {
            printString("Byte.valueOf((byte)");
            printString((aByte).toString());
            printString(")");
    }

    public void printCharacter(Character aCharacter) {
            printString("Character.valueOf('");
            printString((aCharacter).toString());
            printString("')");
    }
}
