/*-
 * 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.sling.dynamicinclude;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.dynamicinclude.pathmatcher.PathMatcher;
import org.apache.sling.dynamicinclude.pathmatcher.PrefixPathMatcher;
import org.apache.sling.dynamicinclude.pathmatcher.RegexPathMatcher;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Include filter configuration.
 */
@Component(service = Configuration.class,
    immediate = true,
    configurationPolicy = ConfigurationPolicy.REQUIRE,
    property = {
        Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
        "webconsole.configurationFactory.nameHint={include-filter.config.include-type} for [{include-filter.config.resource-types}] at path: {include-filter.config.path}"
    })
@Designate(ocd = Configuration.Config.class, factory = true)
public class Configuration {
    
  @ObjectClassDefinition(name = "Apache Sling Dynamic Include - Configuration")
  public @interface Config {
      @AttributeDefinition(name="Enabled", description="Check to enable the filter")
      boolean include$_$filter_config_enabled() default false;
      
      @AttributeDefinition(name="Base path regular expression", description="This SDI configuration will work only for paths matching this value. If value starts with \\\"^\\\" sign, regex matching will be performed. Otherwise it will check for path prefix.")
      String include$_$filter_config_path() default "/content";
      
      @AttributeDefinition(name="Resource types", description="Filter will replace components with selected resource types", cardinality = Integer.MAX_VALUE)
      String include$_$filter_config_resource$_$types() default "";
      
      @AttributeDefinition(name = "Include type", description = "Type of generated include tags", options = {
          @Option(label = "Apache SSI", value = "SSI"),
          @Option(label = "ESI", value = "ESI"),
          @Option(label = "Javascript", value = "JSI")
      })
      String include$_$filter_config_include$_$type() default "SSI";
      
      @AttributeDefinition(name="Add comment", description = "Add comment to included components")
      boolean include$_$filter_config_add__comment() default false;
      
      @AttributeDefinition(name = "Filter selector", description = "Selector used to mark included resources")
      String include$_$filter_config_selector() default "nocache";

      @AttributeDefinition(name = "Extension", description = "Extension to append to virtual resources to make caching possible")
      String include$_$filter_config_extension() default "";

      @AttributeDefinition(name = "Component TTL", description = "\"Time to live\" cache header for rendered component (in seconds)")
      String include$_$filter_config_ttl() default "";

      @AttributeDefinition(name = "Required header", description = "SDI will work only for requests with given header")
      String include$_$filter_config_required__header() default "Server-Agent=Communique-Dispatcher";

      @AttributeDefinition(name = "Ignore URL params", description = "SDI will process the request even if it contains configured GET parameters", cardinality = Integer.MAX_VALUE)
      String include$_$filter_config_ignoreUrlParams() default "";

      @AttributeDefinition(name =  "Include path rewriting", description = "Check to enable include path rewriting")
      boolean include$_$filter_config_rewrite() default false;

      @AttributeDefinition(name =  "Append suffix to dynamic includes", description = "Check to append the suffix of the parent request to the dynamic include.")
      boolean include$_$filter_config_appendSuffix() default true;

      @AttributeDefinition(name =  "Disable ignore URL params check", description = "Disable the check in the Ignore URL Params setting.")
      boolean include$_$filter_config_disableIgnoreUrlParams() default false;
  }

  private static final Logger LOG = LoggerFactory.getLogger(Configuration.class);

  private PathMatcher pathMatcher;

  private boolean isEnabled;

  private String includeSelector;

  private String extension;

  private int ttl;

  private List<String> resourceTypes;

  private boolean addComment;

  private String includeTypeName;

  private String requiredHeader;

  private boolean disableIgnoreUrlParams;

  private List<String> ignoreUrlParams;

  private boolean rewritePath;

  private boolean appendSuffix;

  @Activate
  public void activate(Config cfg) {
    isEnabled = cfg.include$_$filter_config_enabled();
    String pathPattern = cfg.include$_$filter_config_path();
    pathMatcher = choosePathMatcher(pathPattern);
    String[] resourceTypeList;
    resourceTypeList = PropertiesUtil.toStringArray(cfg.include$_$filter_config_resource$_$types(), new String[0]);
    for (int i = 0; i < resourceTypeList.length; i++) {
      String[] s = resourceTypeList[i].split(";");
      String name = s[0].trim();
      resourceTypeList[i] = name;
    }
    this.resourceTypes = Arrays.asList(resourceTypeList);

    includeSelector = cfg.include$_$filter_config_selector();
    extension = cfg.include$_$filter_config_extension();
    ttl = PropertiesUtil.toInteger(cfg.include$_$filter_config_ttl(), -1);
    addComment = cfg.include$_$filter_config_add__comment();
    includeTypeName = cfg.include$_$filter_config_include$_$type();
    requiredHeader = cfg.include$_$filter_config_required__header();
    ignoreUrlParams = Arrays.asList(PropertiesUtil.toStringArray(cfg.include$_$filter_config_ignoreUrlParams(),
        new String[0]));
    rewritePath = cfg.include$_$filter_config_rewrite();
    appendSuffix = cfg.include$_$filter_config_appendSuffix();
    disableIgnoreUrlParams = cfg.include$_$filter_config_disableIgnoreUrlParams();
  }

  private PathMatcher choosePathMatcher(String pathPattern) {
    PathMatcher result;
    if (pathPattern.startsWith("^")) {
      LOG.debug("Configured path value: {} is a regexp - will use a RegexPathMatcher.", pathPattern);
      result = new RegexPathMatcher(pathPattern);
    } else {
      LOG.debug("Configured path value: {} is NOT a regexp - will use a PrefixPathMatcher.", pathPattern);
      result = new PrefixPathMatcher(pathPattern);
    }
    return result;
  }

  public PathMatcher getPathMatcher() {
    return pathMatcher;
  }

  public boolean hasIncludeSelector(SlingHttpServletRequest request) {
    return ArrayUtils.contains(request.getRequestPathInfo().getSelectors(), includeSelector);
  }

  public String getIncludeSelector() {
    return includeSelector;
  }

  public boolean hasExtension(final SlingHttpServletRequest request) {
    final String suffix = request.getRequestPathInfo().getSuffix();
    return suffix.endsWith("." + this.extension);
  }

  public boolean hasExtensionSet() {
    return StringUtils.isNotBlank(this.extension);
  }

  public String getExtension() {
    return this.extension;
  }

  public boolean hasTtlSet() {
    return ttl >= 0;
  }

  public int getTtl() {
    return ttl;
  }

  public boolean isSupportedResourceType(String resourceType) {
    return StringUtils.isNotBlank(resourceType) && resourceTypes.contains(resourceType);
  }

  public boolean getAddComment() {
    return addComment;
  }

  public String getIncludeTypeName() {
    return includeTypeName;
  }

  public boolean isEnabled() {
    return isEnabled;
  }

  public String getRequiredHeader() {
    return requiredHeader;
  }

  public List<String> getIgnoreUrlParams() {
    return ignoreUrlParams;
  }

  public boolean isDisableIgnoreUrlParams() {
    return disableIgnoreUrlParams;
  }

  public boolean isRewritePath() {
    return rewritePath;
  }

  public boolean isAppendSuffix() {
      return appendSuffix;
  }
}
