/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.activemq.bugs;

import jakarta.jms.Connection;
import jakarta.jms.Message;
import jakarta.jms.MessageConsumer;
import jakarta.jms.MessageProducer;
import jakarta.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ActiveMQSession;
import org.apache.activemq.broker.BrokerTestSupport;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQMapMessage;
import org.apache.activemq.command.ActiveMQObjectMessage;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTextMessage;
import org.apache.activemq.usecases.MyObject;
import org.junit.Ignore;

import junit.framework.Test;
import org.junit.experimental.categories.Category;
import org.apache.activemq.test.annotations.ParallelTest;


/**
 * AMQ-6477 changes the behavior to only clear memory if the marshalled state exists
 * so this test no longer works
 */
@Ignore
@Category(ParallelTest.class)
public class AMQ2103Test extends BrokerTestSupport {
    static PolicyEntry reduceMemoryFootprint = new PolicyEntry();
    static {
        reduceMemoryFootprint.setReduceMemoryFootprint(true);
    }

    public PolicyEntry defaultPolicy = reduceMemoryFootprint;

    @Override
    protected PolicyEntry getDefaultPolicy() {
        return defaultPolicy;
    }

    public void initCombosForTestVerifyMarshalledStateIsCleared() throws Exception {
        addCombinationValues("defaultPolicy", new Object[]{defaultPolicy, null});
    }

    public static Test suite() {
        return suite(AMQ2103Test.class);
    }

    /**
     * use mem persistence so no marshaling,
     * reduceMemoryFootprint on/off that will reduce memory by whacking the marshaled state
     * With vm transport and deferred serialisation and no persistence (mem persistence),
     * we see the message as sent by the client so we can validate the contents against
     * the policy
     *
     *
     * @throws Exception
     */
    public void testVerifyMarshalledStateIsCleared() throws Exception {

        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
        factory.setOptimizedMessageDispatch(true);
        factory.setObjectMessageSerializationDefered(true);
        factory.setCopyMessageOnSend(false);

        Connection connection = factory.createConnection();
        Session session = (ActiveMQSession)connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        ActiveMQDestination destination = new ActiveMQQueue("testQ");
		MessageConsumer consumer = session.createConsumer(destination);
		connection.start();

        MessageProducer producer = session.createProducer(destination);
        final MyObject obj = new MyObject("A message");
        ActiveMQObjectMessage m1 = (ActiveMQObjectMessage)session.createObjectMessage();
        m1.setObject(obj);
        producer.send(m1);

        ActiveMQTextMessage m2 = new ActiveMQTextMessage();
        m2.setText("Test Message Payload.");
        producer.send(m2);

        ActiveMQMapMessage m3 = new ActiveMQMapMessage();
        m3.setString("text", "my message");
        producer.send(m3);

        Message m = consumer.receive(maxWait);
        assertNotNull(m);
        assertEquals(m1.getMessageId().toString(), m.getJMSMessageID());
        assertTrue(m instanceof ActiveMQObjectMessage);

        if (getDefaultPolicy() != null) {
            assertNull("object data cleared by reduceMemoryFootprint (and never marshalled as using mem persistence)",
                ((ActiveMQObjectMessage)m).getObject());
        }

        // verify no serialisation via vm transport
        assertEquals("writeObject called", 0, obj.getWriteObjectCalled());
        assertEquals("readObject called", 0, obj.getReadObjectCalled());
        assertEquals("readObjectNoData called", 0, obj.getReadObjectNoDataCalled());

        m = consumer.receive(maxWait);
        assertNotNull(m);
        assertEquals(m2.getMessageId().toString(), m.getJMSMessageID());
        assertTrue(m instanceof ActiveMQTextMessage);

        if (getDefaultPolicy() != null) {
            assertNull("text cleared by reduceMemoryFootprint (and never marshalled as using mem persistence)",
                ((ActiveMQTextMessage)m).getText());
        }

        m = consumer.receive(maxWait);
        assertNotNull(m);
        assertEquals(m3.getMessageId().toString(), m.getJMSMessageID());
        assertTrue(m instanceof ActiveMQMapMessage);

        if (getDefaultPolicy() != null) {
            assertNull("text cleared by reduceMemoryFootprint (and never marshalled as using mem persistence)",
                ((ActiveMQMapMessage)m).getStringProperty("text"));
        }

        connection.close();
    }
}
