//  Copyright 2004, 2008 The Apache Software Foundation
//
// Licensed 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.tapestry.engine;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.tapestry.ApplicationRuntimeException;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.record.SessionPageRecorder;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.*;

/**
 * Concrete implementation of {@link org.apache.tapestry.IEngine} used for ordinary applications.  All page state
 * information is maintained in the {@link javax.servlet.http.HttpSession} using instances of {@link
 * org.apache.tapestry.record.SessionPageRecorder}.
 *
 * @author Howard Lewis Ship
 * @version $Id$
 */

public class BaseEngine extends AbstractEngine
{
    private static final long serialVersionUID = -7051050643746333380L;

    private transient Map _recorders;

    private transient Set _activePageNames;

    /**
     * Removes all page recorders that contain no changes, or are marked for discard.  Subclasses should invoke this
     * implementation in addition to providing thier own.
     */

    protected void cleanupAfterRequest(IRequestCycle cycle)
    {
        if (Tapestry.isEmpty(_recorders))
            return;

        boolean markDirty = false;
        Iterator i = _recorders.entrySet().iterator();

        while (i.hasNext())
        {
            Map.Entry entry = (Map.Entry) i.next();
            String pageName = (String) entry.getKey();
            IPageRecorder recorder = (IPageRecorder) entry.getValue();

            if (!recorder.getHasChanges() || recorder.isMarkedForDiscard())
            {
                recorder.discard();

                i.remove();

                _activePageNames.remove(pageName);

                markDirty = true;
            }
        }

        if (markDirty)
            markDirty();
    }

    public void forgetPage(String name)
    {
        if (_recorders == null)
            return;

        IPageRecorder recorder = (IPageRecorder) _recorders.get(name);
        if (recorder == null)
            return;

        if (recorder.isDirty())
            throw new ApplicationRuntimeException(
                    Tapestry.format("BaseEngine.recorder-has-uncommited-changes", name));

        recorder.discard();
        _recorders.remove(name);
        _activePageNames.remove(name);

        markDirty();
    }

    /**
     * Returns an unmodifiable {@link Collection} of the page names for which {@link IPageRecorder} instances exist.
     */

    public Collection getActivePageNames()
    {
        if (_activePageNames == null)
            return Collections.EMPTY_LIST;

        return Collections.unmodifiableCollection(_activePageNames);
    }

    public IPageRecorder getPageRecorder(String pageName, IRequestCycle cycle)
    {
        if (_activePageNames == null || !_activePageNames.contains(pageName))
            return null;

        IPageRecorder result = null;

        if (_recorders != null)
            return result = (IPageRecorder) _recorders.get(pageName);

        // So the page is active, but not in the cache of page recoders,
        // so (re-)create the page recorder.

        if (result == null)
            result = createPageRecorder(pageName, cycle);

        return result;
    }

    public IPageRecorder createPageRecorder(String pageName, IRequestCycle cycle)
    {
        if (_recorders == null)
            _recorders = new HashMap();
        else
        {
            if (_recorders.containsKey(pageName))
                throw new ApplicationRuntimeException(
                        Tapestry.format("BaseEngine.duplicate-page-recorder", pageName));
        }

        // Force the creation of the HttpSession

        cycle.getRequestContext().createSession();
        setStateful();

        IPageRecorder result = new SessionPageRecorder();
        result.initialize(pageName, cycle);

        _recorders.put(pageName, result);

        if (_activePageNames == null)
            _activePageNames = new HashSet();

        _activePageNames.add(pageName);

        markDirty();

        return result;
    }

    /**
     * Reconstructs the list of active page names written by {@link #writeExternal(ObjectOutput)}.
     */

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
    {
        super.readExternal(in);

        int count = in.readInt();

        if (count > 0)
            _activePageNames = new HashSet(count);

        for (int i = 0; i < count; i++)
        {
            String name = in.readUTF();

            _activePageNames.add(name);
        }

    }

    /**
     * Writes the engine's persistent state; this is simply the list of active page names.  For efficiency, this is
     * written as a count followed by each name as a UTF String.
     */

    public void writeExternal(ObjectOutput out) throws IOException
    {
        super.writeExternal(out);

        if (Tapestry.isEmpty(_activePageNames))
        {
            out.writeInt(0);
            return;
        }

        int count = _activePageNames.size();

        out.writeInt(count);

        Iterator i = _activePageNames.iterator();

        while (i.hasNext())
        {
            String name = (String) i.next();

            out.writeUTF(name);
        }
    }

    public void extendDescription(ToStringBuilder builder)
    {
        builder.append("activePageNames", _activePageNames);
    }

}