/*
 * 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.myfaces.tobago.internal.renderkit.renderer;

import org.apache.myfaces.tobago.component.Attributes;
import org.apache.myfaces.tobago.component.RendererTypes;
import org.apache.myfaces.tobago.component.Tags;
import org.apache.myfaces.tobago.config.TobagoConfig;
import org.apache.myfaces.tobago.context.Markup;
import org.apache.myfaces.tobago.context.Theme;
import org.apache.myfaces.tobago.context.ThemeScript;
import org.apache.myfaces.tobago.context.ThemeStyle;
import org.apache.myfaces.tobago.context.TobagoContext;
import org.apache.myfaces.tobago.internal.component.AbstractUIMeta;
import org.apache.myfaces.tobago.internal.component.AbstractUIMetaLink;
import org.apache.myfaces.tobago.internal.component.AbstractUIPage;
import org.apache.myfaces.tobago.internal.component.AbstractUIScript;
import org.apache.myfaces.tobago.internal.component.AbstractUIStyle;
import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
import org.apache.myfaces.tobago.internal.util.CookieUtils;
import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
import org.apache.myfaces.tobago.internal.util.ResponseUtils;
import org.apache.myfaces.tobago.internal.util.StringUtils;
import org.apache.myfaces.tobago.portlet.PortletUtils;
import org.apache.myfaces.tobago.renderkit.RendererBase;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
import org.apache.myfaces.tobago.renderkit.html.CustomAttributes;
import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
import org.apache.myfaces.tobago.util.ComponentUtils;
import org.apache.myfaces.tobago.util.ResourceUtils;
import org.apache.myfaces.tobago.webapp.Secret;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.enterprise.inject.spi.CDI;
import javax.faces.application.Application;
import javax.faces.application.ProjectStage;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.portlet.MimeResponse;
import javax.portlet.ResourceURL;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;

// using jsf.js from a specific MyFaces version instead, to avoid old bugs
//@ResourceDependency(name="jsf.js", library="javax.faces", target="head")
public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {

  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

  private static final String LAST_FOCUS_ID = "lastFocusId";
  private static final String HEAD_TARGET = "head";
  private static final String BODY_TARGET = "body";

  @Override
  public void decodeInternal(final FacesContext facesContext, final T component) {

    final String clientId = component.getClientId(facesContext);
    final ExternalContext externalContext = facesContext.getExternalContext();

    // last focus
    final String lastFocusId =
        externalContext.getRequestParameterMap().get(clientId + ComponentUtils.SUB_SEPARATOR + LAST_FOCUS_ID);
    if (lastFocusId != null) {
      TobagoContext.getInstance(facesContext).setFocusId(lastFocusId);
    }
  }

//  @Inject // fixme
  private ProjectStage projectStage;

  @Override
  public void encodeBeginInternal(final FacesContext facesContext, final T component) throws IOException {

    final TobagoConfig tobagoConfig = CDI.current().select(TobagoConfig.class).get(); // todo: may inject
    final TobagoContext tobagoContext = CDI.current().select(TobagoContext.class).get(); // todo: may inject

    if (tobagoContext.getFocusId() == null && !StringUtils.isBlank(component.getFocusId())) {
      tobagoContext.setFocusId(component.getFocusId());
    }
    final TobagoResponseWriter writer = getResponseWriter(facesContext);

    // reset responseWriter and render page
    facesContext.setResponseWriter(writer);

    if (tobagoConfig.isPreventFrameAttacks()) {
      ResponseUtils.ensureXFrameOptionsHeader(facesContext);
    }

    ResponseUtils.ensureNoCacheHeader(facesContext);

    ResponseUtils.ensureContentSecurityPolicyHeader(facesContext, tobagoConfig.getContentSecurityPolicy());

    if (LOG.isDebugEnabled()) {
      for (final Object o : component.getAttributes().entrySet()) {
        final Map.Entry entry = (Map.Entry) o;
        LOG.debug("*** '" + entry.getKey() + "' -> '" + entry.getValue() + "'");
      }
    }

    final ExternalContext externalContext = facesContext.getExternalContext();
    final String contextPath = externalContext.getRequestContextPath();
    final Object request = externalContext.getRequest();
    final Object response = externalContext.getResponse();
    final Application application = facesContext.getApplication();
    final ViewHandler viewHandler = application.getViewHandler();
    final UIViewRoot viewRoot = facesContext.getViewRoot();
    final String viewId = viewRoot.getViewId();
    final String formAction = externalContext.encodeActionURL(viewHandler.getActionURL(facesContext, viewId));
    final String partialAction;
    final boolean portlet = PortletUtils.isPortletApiAvailable() && response instanceof MimeResponse;
    if (portlet) {
      final MimeResponse mimeResponse = (MimeResponse) response;
      final ResourceURL resourceURL = mimeResponse.createResourceURL();
      partialAction = externalContext.encodeResourceURL(resourceURL.toString());
    } else {
      partialAction = null;
    }

    final String contentType = writer.getContentTypeWithCharSet();
    ResponseUtils.ensureContentTypeHeader(facesContext, contentType);
    if (tobagoConfig.isSetNosniffHeader()) {
      ResponseUtils.ensureNosniffHeader(facesContext);
    }

    final Theme theme = tobagoContext.getTheme();
    if (response instanceof HttpServletResponse && request instanceof HttpServletRequest) {
      CookieUtils.setThemeNameToCookie((HttpServletRequest) request, (HttpServletResponse) response, theme.getName());
    }

    final String clientId = component.getClientId(facesContext);
    final boolean productionMode = projectStage == ProjectStage.Production;
    final Markup markup = component.getMarkup();
    final TobagoClass spread = markup != null && markup.contains(Markup.SPREAD) ? TobagoClass.SPREAD : null;
    final String title = component.getLabel();

    final Locale locale = viewRoot.getLocale();
    if (!portlet) {
      writer.startElement(HtmlElements.HTML);
      if (locale != null) {
        final String language = locale.getLanguage();
        if (language != null) {
          writer.writeAttribute(HtmlAttributes.LANG, language, false);
        }
      }
    }
    writer.writeClassAttribute(spread);

    writer.startElement(HtmlElements.HEAD);

    final HeadResources headResources = new HeadResources(
        facesContext, viewRoot.getComponentResources(facesContext, HEAD_TARGET), writer.getCharacterEncoding());

    // meta tags
    for (final UIComponent metas : headResources.getMetas()) {
      metas.encodeAll(facesContext);
    }

    // title
    writer.startElement(HtmlElements.TITLE);
    writer.writeText(title != null ? title : "");
    writer.endElement(HtmlElements.TITLE);

    // style files from theme
    AbstractUIStyle style = null;
    for (final ThemeStyle themeStyle : theme.getStyleResources(productionMode)) {
      if (style == null) {
        style = (AbstractUIStyle) facesContext.getApplication()
           .createComponent(facesContext, Tags.style.componentType(), RendererTypes.Style.name());
        style.setTransient(true);
      }
      style.setFile(contextPath + themeStyle.getName());
      style.encodeAll(facesContext);
    }

    // style files individual files
    for (final UIComponent styles : headResources.getStyles()) {
      styles.encodeAll(facesContext);
    }

    // script files from theme
    for (final ThemeScript themeScript : theme.getScriptResources(productionMode)) {
      final AbstractUIScript script = (AbstractUIScript) facesContext.getApplication()
          .createComponent(facesContext, Tags.script.componentType(), RendererTypes.Script.name());
      script.setTransient(true);
      script.setFile(contextPath + themeScript.getName());
      script.setType(themeScript.getType());
      script.encodeAll(facesContext);
    }

    // script files individual files
    for (final UIComponent scripts : headResources.getScripts()) {
      scripts.encodeAll(facesContext);
    }

    for (final UIComponent misc : headResources.getMisc()) {
      misc.encodeAll(facesContext);
    }

    writer.endElement(HtmlElements.HEAD);

    if (!portlet) {
      writer.startElement(HtmlElements.BODY);
      writer.writeClassAttribute(spread);
    }

    writer.startElement(HtmlElements.TOBAGO_PAGE);

    writer.writeAttribute(CustomAttributes.LOCALE, locale.toString(), false);
    writer.writeClassAttribute(
        BootstrapClass.CONTAINER_FLUID,
        TobagoClass.PAGE.createMarkup(portlet ? Markup.PORTLET.add(component.getMarkup()) : component.getMarkup()),
        spread,
        component.getCustomClass());
    writer.writeIdAttribute(clientId);
    HtmlRendererUtils.writeDataAttributes(facesContext, writer, component);

    encodeBehavior(writer, facesContext, component);

    writer.startElement(HtmlElements.FORM);
    writer.writeClassAttribute(spread);
    writer.writeAttribute(HtmlAttributes.ACTION, formAction, true);
    if (partialAction != null) {
      writer.writeAttribute(DataAttributes.PARTIAL_ACTION, partialAction, true);
    }
    if (LOG.isDebugEnabled()) {
      LOG.debug("partial action = " + partialAction);
    }
    writer.writeIdAttribute(component.getFormId(facesContext));
    writer.writeAttribute(HtmlAttributes.METHOD, getMethod(component), false);
    final String enctype = tobagoContext.getEnctype();
    if (enctype != null) {
      writer.writeAttribute(HtmlAttributes.ENCTYPE, enctype, false);
    }
    // TODO: enable configuration of  'accept-charset'
    writer.writeAttribute(HtmlAttributes.ACCEPT_CHARSET, AbstractUIPage.FORM_ACCEPT_CHARSET.name(), false);
    // TODO evaluate 'accept' attribute usage
    //writer.writeAttribute(HtmlAttributes.ACCEPT, );
    writer.writeAttribute(DataAttributes.CONTEXT_PATH, contextPath, true);

    writer.startElement(HtmlElements.INPUT);
    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
    writer.writeNameAttribute("javax.faces.source");
    writer.writeIdAttribute("javax.faces.source");
    writer.writeAttribute(HtmlAttributes.DISABLED, true);
    writer.endElement(HtmlElements.INPUT);

    final String lastFocusId = clientId + ComponentUtils.SUB_SEPARATOR + "lastFocusId";
    writer.startElement(HtmlElements.TOBAGO_FOCUS);
    writer.writeIdAttribute(lastFocusId);
    writer.startElement(HtmlElements.INPUT);
    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
    writer.writeNameAttribute(lastFocusId);
    writer.writeIdAttribute(lastFocusId + ComponentUtils.SUB_SEPARATOR + "field");
    writer.writeAttribute(HtmlAttributes.VALUE, tobagoContext.getFocusId(), true);
    writer.endElement(HtmlElements.INPUT);
    writer.endElement(HtmlElements.TOBAGO_FOCUS);

    if (tobagoConfig.isCheckSessionSecret()) {
      writer.startElement(HtmlElements.INPUT);
      writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
      writer.writeAttribute(HtmlAttributes.NAME, Secret.KEY, false);
      writer.writeAttribute(HtmlAttributes.ID, Secret.KEY, false);
//      final Object session = facesContext.getExternalContext().getSession(true);
      final Secret secret = CDI.current().select(Secret.class).get();
      secret.encode(writer);
      writer.endElement(HtmlElements.INPUT);
    }

    if (component.getFacet("backButtonDetector") != null) {
      final UIComponent hidden = component.getFacet("backButtonDetector");
      hidden.encodeAll(facesContext);
    }
  }

// TODO: this is needed for the "BACK-BUTTON-PROBLEM"
// but may no longer needed
/*
    if (ViewHandlerImpl.USE_VIEW_MAP) {
      writer.startElement(HtmlElements.INPUT, null);
      writer.writeAttribute(HtmlAttributes.type, "hidden", null);
      writer.writeNameAttribute(ViewHandlerImpl.PAGE_ID);
      writer.writeIdAttribute(ViewHandlerImpl.PAGE_ID);
      Object value = facesContext.getViewRoot().getAttributes().get(
          ViewHandlerImpl.PAGE_ID);
      writer.writeAttribute(HtmlAttributes.value, (value != null ? value : ""), null);
      writer.endElement(HtmlElements.INPUT);
    }
*/

  @Override
  public void encodeEndInternal(final FacesContext facesContext, final T component) throws IOException {

    final UIViewRoot viewRoot = facesContext.getViewRoot();
    final TobagoResponseWriter writer = getResponseWriter(facesContext);
    final String clientId = component.getClientId(facesContext);
    final Application application = facesContext.getApplication();
    final ViewHandler viewHandler = application.getViewHandler();
    final Object response = facesContext.getExternalContext().getResponse();
    final boolean portlet = PortletUtils.isPortletApiAvailable() && response instanceof MimeResponse;
    final boolean ajax = facesContext.getPartialViewContext().isAjaxRequest();

    // placeholder for menus
    writer.startElement(HtmlElements.DIV);
    writer.writeClassAttribute(TobagoClass.PAGE__MENU_STORE);
    writer.endElement(HtmlElements.DIV);

    writer.startElement(HtmlElements.SPAN);
    writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "jsf-state-container");
    writer.flush();
    if (!ajax) {
      viewHandler.writeState(facesContext);
    }
    writer.endElement(HtmlElements.SPAN);

    writer.endElement(HtmlElements.FORM);

    writer.startElement(HtmlElements.NOSCRIPT);
    writer.startElement(HtmlElements.DIV);
    writer.writeClassAttribute(TobagoClass.PAGE__NOSCRIPT);
    writer.writeText(ResourceUtils.getString(facesContext, "page.noscript"));
    writer.endElement(HtmlElements.DIV);
    writer.endElement(HtmlElements.NOSCRIPT);
    writer.endElement(HtmlElements.TOBAGO_PAGE);

    final List<UIComponent> bodyResources = viewRoot.getComponentResources(facesContext, BODY_TARGET);
    for (final UIComponent bodyResource : bodyResources) {
      bodyResource.encodeAll(facesContext);
    }

    if (!portlet) {
      writer.endElement(HtmlElements.BODY);
      writer.endElement(HtmlElements.HTML);
    }

    AccessKeyLogger.logStatus(facesContext);
  }

  private String getMethod(final AbstractUIPage page) {
    return ComponentUtils.getStringAttribute(page, Attributes.method, "post");
  }

  @Override
  public boolean getRendersChildren() {
    return true;
  }

  /**
   * This class helps to order the head resources.
   */
  private static class HeadResources {

    private List<UIComponent> metas = new ArrayList<>();
    private List<UIComponent> styles = new ArrayList<>();
    private List<UIComponent> scripts = new ArrayList<>();
    private List<UIComponent> misc = new ArrayList<>();

    HeadResources(
        final FacesContext facesContext, final Collection<? extends UIComponent> collection, final String charset) {
      for (final UIComponent uiComponent : collection) {
        if (uiComponent instanceof AbstractUIMeta || uiComponent instanceof AbstractUIMetaLink) {
          metas.add(uiComponent);
        } else if (uiComponent instanceof AbstractUIStyle) {
          styles.add(uiComponent);
        } else if (uiComponent instanceof AbstractUIScript) {
          scripts.add(uiComponent);
        } else {
          if (uiComponent instanceof UIOutput) {
            final Map<String, Object> attributes = uiComponent.getAttributes();
            if ("javax.faces".equals(attributes.get("library"))
                && "jsf.js".equals(attributes.get("name"))) {
              // workaround for WebSphere
              // We don't need jsf.js from the JSF impl, because Tobago comes with its own jsf.js
              if (LOG.isDebugEnabled()) {
                LOG.debug("Skip rendering resource jsf.js");
              }
              continue;
            }
          }
          misc.add(uiComponent);
        }
      }

      if (!containsNameViewport(metas)) {
        final AbstractUIMeta viewportMeta = (AbstractUIMeta) facesContext.getApplication()
            .createComponent(facesContext, Tags.meta.componentType(), RendererTypes.Meta.name());
        viewportMeta.setName("viewport");
        viewportMeta.setContent("width=device-width, initial-scale=1.0");
        viewportMeta.setTransient(true);
        metas.add(0, viewportMeta);
      }

      if (!containsCharset(metas)) {
        final AbstractUIMeta charsetMeta = (AbstractUIMeta) facesContext.getApplication()
            .createComponent(facesContext, Tags.meta.componentType(), RendererTypes.Meta.name());
        charsetMeta.setCharset(charset);
        charsetMeta.setTransient(true);
        metas.add(0, charsetMeta);
      }
    }

    public List<UIComponent> getMetas() {
      return metas;
    }

    public List<UIComponent> getStyles() {
      return styles;
    }

    public List<UIComponent> getScripts() {
      return scripts;
    }

    public List<UIComponent> getMisc() {
      return misc;
    }

    private boolean containsCharset(final List<UIComponent> headComponents) {
      for (final UIComponent headComponent : headComponents) {
        if (headComponent instanceof AbstractUIMeta
            && ((AbstractUIMeta) headComponent).getCharset() != null) {
          return true;
        }
      }
      return false;
    }

    private boolean containsNameViewport(final List<UIComponent> headComponents) {
      for (final UIComponent headComponent : headComponents) {
        if (headComponent instanceof AbstractUIMeta
            && "viewport".equals(((AbstractUIMeta) headComponent).getName())) {
          return true;
        }
      }
      return false;
    }

  }
}
