/*
 * Copyright (c) 2011, 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:
//      tware - initial
package org.eclipse.persistence.jpa.rs.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.logging.Level;

import jakarta.ws.rs.core.MediaType;

import org.eclipse.persistence.internal.jpa.rs.weaving.PersistenceWeavedRest;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.rs.DataStorage;
import org.eclipse.persistence.jpa.rs.PersistenceContext;
import org.eclipse.persistence.jpa.rs.logging.LoggingLocalization;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.logging.SessionLogEntry;
import org.eclipse.persistence.sessions.Session;

/**
 * Logger for EclipseLink JPA-RS related functionality.
 * Publishes messages under the {@link SessionLog#JPARS} category.
 */
public class JPARSLogger {

    private static final SessionLog defaultLog = AbstractSessionLog.getLog();

    /**
     * Entering
     *
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param params parameters
     */
    public static void entering(String sourceClass, String sourceMethod, Object[] params) {
        entering(defaultLog, sourceClass, sourceMethod, params);
    }

    /**
     * Entering
     *
     * @param sessionLog the log
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param params parameters
     */
    public static void entering(SessionLog sessionLog, String sourceClass, String sourceMethod, Object[] params) {
        // Logger logs entering logs when log level <= FINER. But, we want to get these logs created only when the log level is FINEST.
        if (isLoggableFinest(sessionLog)) {
            SessionLogEntry sle = newLogEntry(sessionLog.getSession());
            sle.setSourceClassName(sourceClass);
            sle.setSourceMethodName(sourceMethod);
            sle.setMessage("ENTRY {0}");
            sle.setParameters(getParamsWithAdditionalInfo(params));
            sessionLog.log(sle);
        }
    }

    /**
     * Entering
     *
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param in the input stream
     */
    public static void entering(String sourceClass, String sourceMethod, InputStream in) {
        entering(defaultLog, sourceClass, sourceMethod, in);
    }

    /**
     * Entering
     *
     * @param sessionLog log receiving the message
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param in the input stream
     */
    public static void entering(SessionLog sessionLog, String sourceClass, String sourceMethod, InputStream in) {
        // Logger logs entering logs when log level <= FINER. But, we want to get these logs created only when the log level is FINEST.

        // make sure input stream supports mark so that the or create a new BufferedInputStream which supports mark.
        // when mark is supported, the stream remembers all the bytes read after the call to mark and
        // stands ready to supply those same bytes again if and whenever the method reset is called.
        if (isLoggableFinest(sessionLog) && (in.markSupported())) {
            try {
                String data = readData(in);
                in.reset();
                if (data != null) {
                    SessionLogEntry sle = newLogEntry(sessionLog.getSession());
                    sle.setSourceClassName(sourceClass);
                    sle.setSourceMethodName(sourceMethod);
                    sle.setMessage("ENTRY {0}");
                    sle.setParameters(getParamsWithAdditionalInfo(new Object[] { data }));
                    sessionLog.log(sle);
                }
            } catch (Throwable throwable) {
                exception(throwable.getMessage(), new Object[] {}, throwable);
            }
        }
    }

    /**
     * Exiting
     *
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param params parameters
     */
    public static void exiting(String sourceClass, String sourceMethod, Object[] params) {
        exiting(defaultLog, sourceClass, sourceMethod, params);
    }

    /**
     * Exiting
     *
     * @param sessionLog the log
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param params parameters
     */
    public static void exiting(SessionLog sessionLog, String sourceClass, String sourceMethod, Object[] params) {
        // Logger logs exiting logs when log level <= FINER. But, we want to get these logs created only when the log level is FINEST.
        if (isLoggableFinest()) {
            try {
                SessionLogEntry sle = newLogEntry(sessionLog.getSession());
                sle.setSourceClassName(sourceClass);
                sle.setSourceMethodName(sourceMethod);
                sle.setMessage("RETURN {0}");
                sle.setParameters(new Object[] {new MethodExitLogData(getParamsWithAdditionalInfo(params))});
                sessionLog.log(sle);
            } catch (Throwable throwable) {
                exception(throwable.getMessage(), new Object[] {}, throwable);
            }
        }
    }

    /**
     * Exiting
     *
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param context the context
     * @param object the object
     * @param mediaType the media type
     */
    public static void exiting(String sourceClass, String sourceMethod, PersistenceContext context, Object object, MediaType mediaType) {
        exiting(defaultLog, sourceClass, sourceMethod, context, object, mediaType);
    }

    /**
     * Exiting
     *
     * @param sessionLog the log
     * @param sourceClass the source class
     * @param sourceMethod the source method
     * @param context the context
     * @param object the object
     * @param mediaType the media type
     */
    public static void exiting(SessionLog sessionLog, String sourceClass, String sourceMethod, PersistenceContext context, Object object, MediaType mediaType) {
        // Log marshaled object only when the log level is FINEST
        if (isLoggableFinest(sessionLog) && (context != null) && (object != null) && (mediaType != null)) {
            try {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                context.marshall(object, mediaType, outputStream, true);
                if (object instanceof PersistenceWeavedRest) {
                    exiting(sessionLog, sourceClass, sourceMethod, new Object[] { object.getClass().getName(), outputStream.toString(StandardCharsets.UTF_8.name())});
                } else {
                    exiting(sessionLog, sourceClass, sourceMethod, new Object[] { outputStream.toString(StandardCharsets.UTF_8.name()) });
                }
            } catch (Throwable throwable) {
                exception(throwable.getMessage(), new Object[] {}, throwable);
            }
        }
    }

    /**
     * Finest
     *
     * @param message the message
     * @param params parameters
     */
    public static void finest(String message, Object[] params) {
        finest(defaultLog, message, params);
    }

    /**
     * Finest
     *
     * @param sessionLog the log
     * @param message the message
     * @param params parameters
     */
    public static void finest(SessionLog sessionLog, String message, Object[] params) {
        log(sessionLog, SessionLog.FINEST, message, getParamsWithAdditionalInfo(params));
    }

    /**
     * Fine
     *
     * @param message the message
     * @param params parameters
     */
    public static void fine(String message, Object[] params) {
        fine(defaultLog, message, params);
    }

    /**
     * Fine
     *
     * @param sessionLog the log
     * @param message the message
     * @param params parameters
     */
    public static void fine(SessionLog sessionLog, String message, Object[] params) {
        log(sessionLog, SessionLog.FINE, message, getParamsWithAdditionalInfo(params));
    }

    /**
     * Warning
     *
     * @param message the message
     * @param params parameters
     */
    public static void warning(String message, Object[] params) {
        warning(defaultLog, message, params);
    }

    /**
     * Warning
     *
     * @param sessionLog the log
     * @param message the message
     * @param params parameters
     */
    public static void warning(SessionLog sessionLog, String message, Object[] params) {
        log(sessionLog, SessionLog.WARNING, message, getParamsWithAdditionalInfo(params));
    }

    /**
     * Error
     *
     * @param message the message
     * @param params parameters
     */
    public static void error(String message, Object[] params) {
        error(defaultLog, message, params);
    }

    /**
     * Error
     *
     * @param sessionLog the log
     * @param message the message
     * @param params parameters
     */
    public static void error(SessionLog sessionLog, String message, Object[] params) {
        log(sessionLog, SessionLog.SEVERE, message, getParamsWithAdditionalInfo(params));
    }

    /**
     * Exception
     *
     * @param message the message
     * @param params parameters
     * @param exc the throwable
     */
    public static void exception(String message, Object[] params, Throwable exc) {
        exception(defaultLog, message, params, exc);
    }

    /**
     * Exception
     *
     * @param sessionLog the log
     * @param message the message
     * @param params parameters
     * @param exc the throwable
     */
    public static void exception(SessionLog sessionLog, String message, Object[] params, Throwable exc) {
        log(sessionLog, SessionLog.SEVERE, message, getParamsWithAdditionalInfo(params), exc);
    }

    /**
     * Sets the log level
     *
     * @param level the new log level
     */
    public static void setLogLevel(Level level) {
        setLogLevel(defaultLog, AbstractSessionLog.translateStringToLoggingLevel(level.getName()));
    }

    /**
     * Sets the log level
     *
     * @param sessionLog the log
     * @param level the new log level
     */
    public static void setLogLevel(SessionLog sessionLog, int level) {
        sessionLog.setLevel(level, SessionLog.JPARS);
    }

    /**
     * @return true if log level is set to {@link SessionLog#FINEST}
     */
    public static boolean isLoggableFinest() {
        return isLoggableFinest(defaultLog);
    }

    /**
     * @param sessionLog the log
     *
     * @return true if log level is set to {@link SessionLog#FINEST}
     */
    public static boolean isLoggableFinest(SessionLog sessionLog) {
        return sessionLog.shouldLog(SessionLog.FINEST, SessionLog.JPARS);
    }

    private static Object[] getParamsWithAdditionalInfo(Object[] params) {
        String requestId = (String) DataStorage.get(DataStorage.REQUEST_ID);
        if (params != null) {
            Object[] paramsWithRequestId = new Object[params.length + 1];
            paramsWithRequestId[0] = requestId;
            System.arraycopy(params, 0, paramsWithRequestId, 1, params.length);
            return paramsWithRequestId;
        }
        return new Object[] { requestId };
    }

    private static void log(SessionLog sessionLog, int level, String message, Object[] params) {
        log(sessionLog, level, message, params, null);
    }

    private static void log(SessionLog sessionLog, int level, String message, Object[] params, Throwable t) {
        Objects.requireNonNull(sessionLog);
        if (sessionLog.shouldLog(level, SessionLog.JPARS)) {
            SessionLogEntry sle = newLogEntry(sessionLog.getSession());
            sle.setLevel(level);
            sle.setMessage(LoggingLocalization.buildMessage(message, params));
            sle.setParameters(params);
            sle.setException(t);
            sessionLog.log(sle);
        }
    }

    private static SessionLogEntry newLogEntry(Session session) {
        SessionLogEntry entry = session instanceof AbstractSession
                ? new SessionLogEntry((AbstractSession) session)
                : new SessionLogEntry(null);
        entry.setLevel(SessionLog.FINEST);
        entry.setNameSpace(SessionLog.JPARS);
        entry.setShouldTranslate(false);
        return entry;
    }

    private static String readData(InputStream is) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        ByteArrayInputStream bais = null;
        int nRead;
        byte[] data = new byte[16384];
        while ((nRead = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        buffer.flush();
        byte[] bytes = buffer.toByteArray();
        bais = new ByteArrayInputStream(bytes);
        return getDataFromInputStream(bais);
    }

    private static String getDataFromInputStream(InputStream is) {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            // ignore
        }
        return sb.toString();
    }
}
