/*
 * 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 rewrite.org.apache.myfaces.extensions.scripting.jsf.dynamicdecorators.implementations;


import rewrite.org.apache.myfaces.extensions.scripting.core.common.Decorated;
import rewrite.org.apache.myfaces.extensions.scripting.core.common.ScriptingConst;
import rewrite.org.apache.myfaces.extensions.scripting.core.context.WeavingContext;

import javax.el.ELContext;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.application.ProjectStage;
import javax.faces.component.UIViewRoot;
import javax.faces.context.*;
import javax.faces.event.PhaseId;
import javax.faces.render.RenderKit;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * A reloading, weaving  faces context
 * this is needed because groovy fails on
 * the introspection of the standard java myfaces
 * faces context due to pending references
 * of the _impl into the portlet context
 * not sure if this works in portlets
 * though
 *
 * @author Werner Punz
 */
public class FacesContextProxy extends FacesContext implements Decorated
{

    public FacesContext _delegate = null;

    private void weaveDelegate() {
        //in case of a context destroyed the weaver might be accessed a last time
        //but is already null due to having no weaver in the shutdown thread
        if (_delegate != null && WeavingContext.getInstance().isScriptingEnabled())
            _delegate = (FacesContext) WeavingContext.getInstance().reload(_delegate,
                    ScriptingConst.ARTIFACT_TYPE_FACESCONTEXT);
    }

    public ELContext getELContext() {
        return _delegate.getELContext();
    }

    public Application getApplication() {
        return _delegate.getApplication();
    }

    public Iterator<String> getClientIdsWithMessages() {
        return _delegate.getClientIdsWithMessages();
    }

    public ExternalContext getExternalContext() {
        return _delegate.getExternalContext();
    }

    public FacesMessage.Severity getMaximumSeverity() {
        return _delegate.getMaximumSeverity();
    }

    public Iterator<FacesMessage> getMessages() {
        return _delegate.getMessages();
    }

    public Iterator<FacesMessage> getMessages(String s) {
        return _delegate.getMessages(s);
    }

    public RenderKit getRenderKit() {
        return _delegate.getRenderKit();
    }

    public boolean getRenderResponse() {
        return _delegate.getRenderResponse();
    }

    public boolean getResponseComplete() {
        return _delegate.getResponseComplete();
    }

    public ResponseStream getResponseStream() {
        return _delegate.getResponseStream();
    }

    public void setResponseStream(ResponseStream responseStream) {
        _delegate.setResponseStream(responseStream);
    }

    public ResponseWriter getResponseWriter() {
        return _delegate.getResponseWriter();
    }

    public void setResponseWriter(ResponseWriter responseWriter) {
        _delegate.setResponseWriter(responseWriter);
    }

    public UIViewRoot getViewRoot() {
        return _delegate.getViewRoot();
    }

    public void setViewRoot(UIViewRoot uiViewRoot) {
        weaveDelegate();//perfect place no matter what the viewRoot is about once per request set
        _delegate.setViewRoot(uiViewRoot);
    }

    public void addMessage(String s, FacesMessage facesMessage) {
        _delegate.addMessage(s, facesMessage);
    }

    public void release() {
        _delegate.release();
    }

    public void renderResponse() {
        _delegate.renderResponse();
    }

    public void responseComplete() {
        _delegate.responseComplete();
    }

    public FacesContextProxy(FacesContext delegate) {
        _delegate = delegate;
        weaveDelegate();
    }

    @Override
    public Map<Object, Object> getAttributes() {
        return _delegate.getAttributes();
    }

    @Override
    public PhaseId getCurrentPhaseId() {
        return _delegate.getCurrentPhaseId();
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        return _delegate.getExceptionHandler();
    }

    @Override
    public List<FacesMessage> getMessageList() {
        return _delegate.getMessageList();
    }

    @Override
    public List<FacesMessage> getMessageList(String s) {
        return _delegate.getMessageList(s);
    }

    @Override
    public PartialViewContext getPartialViewContext() {
        return _delegate.getPartialViewContext();
    }

    @Override
    public boolean isValidationFailed() {
        return _delegate.isValidationFailed();
    }

    @Override
    public boolean isPostback() {
        return _delegate.isPostback();
    }

    @Override
    public boolean isProcessingEvents() {
        return _delegate.isProcessingEvents();
    }

    @Override
    public void setCurrentPhaseId(PhaseId phaseId) {
        _delegate.setCurrentPhaseId(phaseId);
    }

    @Override
    public void setExceptionHandler(ExceptionHandler exceptionHandler) {
        _delegate.setExceptionHandler(exceptionHandler);
    }

    @Override
    public void setProcessingEvents(boolean b) {
        _delegate.setProcessingEvents(b);
    }

    @Override
    public void validationFailed() {
        _delegate.validationFailed();
    }

    @Override
    public boolean isProjectStage(ProjectStage projectStage) {
        return _delegate.isProjectStage(projectStage);
    }

    public Object getDelegate() {
        return _delegate;
    }
}
