/**********************************************************************
Copyright (c) 2014 HubSpot Inc.

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 com.hubspot.jinjava.lib.tag;

import static com.hubspot.jinjava.util.Logging.ENGINE_LOG;

import java.io.IOException;

import org.apache.commons.lang3.StringUtils;

import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.Context;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.tree.Node;
import com.hubspot.jinjava.tree.TagNode;
import com.hubspot.jinjava.util.HelperStringTokenizer;


@JinjavaDoc(value="includes the template at the specified path at this position",
    params={
      @JinjavaParam("path")
    },
    snippets={
      @JinjavaSnippet(code="{% include 'sidebar.html'%}"),
      @JinjavaSnippet(code="{% include var_fileName %}")
    })
public class IncludeTag implements Tag {
  private static final String INCLUDE_PATH_PROPERTY = "__includeP@th__";

  @Override
  public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
    HelperStringTokenizer helper = new HelperStringTokenizer(tagNode.getHelpers());
    if (!helper.hasNext()) {
      throw new InterpretException("Tag 'include' expects template path", tagNode.getLineNumber());
    }

    String path = StringUtils.trimToEmpty(helper.next());

    if(isPathInRenderStack(interpreter.getContext(), path)) {
      ENGINE_LOG.debug("Path {} is already in include stack", path);
      return "";
    }

    String templateFile = interpreter.resolveString(path, tagNode.getLineNumber());
    try {
      String template = interpreter.getResource(templateFile);
      Node node = interpreter.parse(template);
      JinjavaInterpreter child = new JinjavaInterpreter(interpreter);
      child.getContext().put(INCLUDE_PATH_PROPERTY, path);
      interpreter.getContext().put(JinjavaInterpreter.INSERT_FLAG, true);
      return child.render(node);
    } catch (IOException e) {
      throw new InterpretException(e.getMessage(), e, tagNode.getLineNumber());
    }
  }

  private boolean isPathInRenderStack(Context context, String path) {
    Context current = context;
    do {
      String includePath = (String) current.get(INCLUDE_PATH_PROPERTY);

      if(StringUtils.equals(path, includePath)) {
        return true;
      }

      current = current.getParent();

    } while(current != null);

    return false;
  }

  @Override
  public String getEndTagName() {
    return null;
  }

  @Override
  public String getName() {
    return "include";
  }

}

@@ -1363,100 +1363,164 @@
 des 
-the template at the specified path at this position%22,%0A    params=%7B%0A      @JinjavaParam(%22path
+multiple files in one template or stylesheet%22,%0A    params=%7B%0A      @JinjavaParam(%22path%22, desc=%22Design Manager path to the file that you would like to include
 %22)%0A 
@@ -1583,22 +1583,54 @@
 ude 
-'sideba
+%5C%22custom/page/web_page_basic/my_foote
 r.html
-'
+%5C%22 
 %25%7D%22)
@@ -1674,25 +1674,145 @@
 ude 
-var_fileName
+%5C%22generated_global_groups/2781996615.html%5C%22 %25%7D%22),%0A      @JinjavaSnippet(code=%22%7B%25 include %5C%22hubspot/styles/patches/recommended.css%5C%22
  %25%7D%22)
+,
 %0A   

include tag params and snippets