/*
 * 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.catalina.session;

import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import org.junit.Assert;
import org.junit.Test;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Session;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.catalina.valves.PersistentValve;

public class TestPersistentManagerIntegration extends TomcatBaseTest {

    /**
     * Wait enough for the system clock to update its value. On some systems
     * (e.g. old Windows) the clock granularity is tens of milliseconds.
     */
    private void waitForClockUpdate() throws InterruptedException {
        long startTime = System.currentTimeMillis();
        int waitTime = 1;
        do {
            Thread.sleep(waitTime);
            waitTime *= 10;
        } while (System.currentTimeMillis() == startTime);
    }

    /**
     * Wait while session access counter has a positive value.
     */
    private void waitWhileSessionIsActive(StandardSession session)
            throws InterruptedException {
        long maxWaitTime = System.currentTimeMillis() + 60000;
        AtomicInteger accessCount = session.accessCount;
        while (accessCount.get() > 0) {
            // Wait until o.a.c.connector.Request.recycle() completes,
            // as it updates lastAccessedTime.
            Assert.assertTrue(System.currentTimeMillis() < maxWaitTime);
            Thread.sleep(200);
        }
    }

    @Test
    public void noSessionCreate_57637() throws IOException, LifecycleException {

        // Setup Tomcat instance
        Tomcat tomcat = getTomcatInstance();

        // No file system docBase required
        StandardContext ctx = (StandardContext) getProgrammaticRootContext();
        ctx.setDistributable(true);

        Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
        ctx.addServletMappingDecoded("/dummy", "DummyServlet");

        PersistentManager manager = new PersistentManager();
        TesterStore store = new TesterStore();

        manager.setStore(store);
        manager.setMaxIdleBackup(0);
        manager.setSessionActivityCheck(true);
        ctx.setManager(manager);
        ctx.addValve(new PersistentValve());
        tomcat.start();
        Assert.assertEquals(manager.getActiveSessions(), 0);
        Assert.assertTrue("No sessions managed", manager.getSessionIdsFull().isEmpty());
        Assert.assertEquals(
                "NO_SESSION",
                getUrl(
                        "http://localhost:" + getPort()
                                + "/dummy?no_create_session=true").toString());
        Assert.assertEquals(manager.getActiveSessions(), 0);
        Assert.assertTrue("No sessions where created", manager.getSessionIdsFull().isEmpty());
    }

    @Test
    public void testCreateSessionAndPassivate() throws IOException, LifecycleException, ClassNotFoundException {

        // Setup Tomcat instance
        Tomcat tomcat = getTomcatInstance();

        // No file system docBase required
        StandardContext ctx = (StandardContext) getProgrammaticRootContext();
        ctx.setDistributable(true);

        Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
        ctx.addServletMappingDecoded("/dummy", "DummyServlet");

        PersistentManager manager = new PersistentManager();
        TesterStore store = new TesterStore();

        manager.setStore(store);
        manager.setMaxIdleBackup(0);
        manager.setSessionActivityCheck(true);
        ctx.setManager(manager);
        ctx.addValve(new PersistentValve());
        tomcat.start();
        Assert.assertEquals("No active sessions", manager.getActiveSessions(), 0);
        Assert.assertTrue("No sessions managed", manager.getSessionIdsFull().isEmpty());
        String sessionId = getUrl(
                "http://localhost:" + getPort()
                        + "/dummy?no_create_session=false").toString();
        Assert.assertNotNull("Session is stored", store.load(sessionId));
        Assert.assertEquals("All sessions are passivated", manager.getActiveSessions(), 0);
        Assert.assertTrue("One session was created", !manager.getSessionIdsFull().isEmpty());
    }

    @Test
    public void backsUpOnce_56698() throws IOException, LifecycleException,
            InterruptedException {

        // Setup Tomcat instance
        Tomcat tomcat = getTomcatInstance();

        // No file system docBase required
        Context ctx = getProgrammaticRootContext();
        ctx.setDistributable(true);

        Tomcat.addServlet(ctx, "DummyServlet", new DummyServlet());
        ctx.addServletMappingDecoded("/dummy", "DummyServlet");

        PersistentManager manager = new PersistentManager();
        TesterStore store = new TesterStore();

        manager.setStore(store);
        manager.setMaxIdleBackup(0);
        manager.setSessionActivityCheck(true);
        ctx.setManager(manager);
        tomcat.start();
        String sessionId = getUrl("http://localhost:" + getPort() + "/dummy")
                .toString();

        // Note: PersistenceManager.findSession() silently updates
        // session.lastAccessedTime, so call it only once before other work.
        Session session = manager.findSession(sessionId);

        // Wait until request processing ends, as Request.recycle() updates
        // session.lastAccessedTime via session.endAccess().
        waitWhileSessionIsActive((StandardSession) session);

        long lastAccessedTime = session.getLastAccessedTimeInternal();

        // Session should be idle at least for 0 second (maxIdleBackup)
        // to be eligible for persistence, thus no need to wait.

        // Waiting a bit, to catch changes in last accessed time of a session
        waitForClockUpdate();

        manager.processPersistenceChecks();
        Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds());
        Assert.assertEquals(lastAccessedTime, session.getLastAccessedTimeInternal());

        // session was not accessed, so no save will be performed
        waitForClockUpdate();
        manager.processPersistenceChecks();
        Assert.assertEquals(Arrays.asList(sessionId), store.getSavedIds());
        Assert.assertEquals(lastAccessedTime, session.getLastAccessedTimeInternal());

        // access session
        session.access();
        session.endAccess();

        // session was accessed, so it will be saved once again
        manager.processPersistenceChecks();
        Assert.assertEquals(Arrays.asList(sessionId, sessionId),
                store.getSavedIds());

        // session was not accessed, so once again no save will happen
        manager.processPersistenceChecks();
        Assert.assertEquals(Arrays.asList(sessionId, sessionId),
                store.getSavedIds());
    }

    private static class DummyServlet extends HttpServlet {

        private static final long serialVersionUID = -3696433049266123995L;

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            boolean createSession = !Boolean.parseBoolean(req
                            .getParameter("no_create_session"));
            HttpSession session = req.getSession(createSession);
            if (session == null) {
                resp.getWriter().print("NO_SESSION");
            } else {
                String id = session.getId();
                resp.getWriter().print(id);
            }
        }

    }
}
