package fitnesse.wikitext.parser;

import fitnesse.wiki.PageData;
import fitnesse.wiki.PathParser;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

public class Include extends SymbolType implements Rule, Translation {
    private static final String[] setUpSymbols = new String[] {"COLLAPSE_SETUP"};
    private static final String includeHelpOption = "-h";
    public static final String TEARDOWN = "teardown";

    public Include() {
        super("Include");
        wikiMatcher(new Matcher().startLineOrCell().string("!include"));
        wikiRule(this);
        htmlTranslation(this);
    }

    @Override
    public Maybe<Symbol> parse(Symbol current, Parser parser) {
        Symbol next = parser.moveNext(1);
        if (!next.isType(SymbolType.Whitespace)) return Symbol.nothing;

        next = parser.moveNext(1);
        String option = "";
        if ((next.isType(SymbolType.Text) && next.getContent().startsWith("-")) || next.isType(SymbolType.DateFormatOption)) {
            option = next.getContent() + (next.isType(SymbolType.DateFormatOption) ? parser.moveNext(1).getContent() : "");
            next = parser.moveNext(1);
            if (!next.isType(SymbolType.Whitespace)) return Symbol.nothing;
            next = parser.moveNext(1);
        }
        current.add(option);
        if (!next.isType(SymbolType.Text) && !next.isType(WikiWord.symbolType)) return Symbol.nothing;

        String includedPageName = next.getContent();
        while (parser.peek().isType(SymbolType.Text) || parser.peek().isType(WikiWord.symbolType)) {
          Symbol remainderOfPageName = parser.moveNext(1);
          includedPageName += remainderOfPageName.getContent();
        }

        SourcePage sourcePage = parser.getPage().getNamedPage();

        // Record the page name anyway, since we might want to show an error if it's invalid
        if (PathParser.isWikiPath(includedPageName)) {
          current.add(new Symbol(new WikiWord(sourcePage), includedPageName));
        } else {
          current.add(includedPageName);
        }

        Maybe<SourcePage> includedPage = sourcePage.findIncludedPage(includedPageName);
        if (includedPage.isNothing()) {
          current.add("").add(new Symbol(SymbolType.Style, "error").add(includedPage.because()));
        }
        else if (includeHelpOption.equals(option)) {
        	String helpText = includedPage.getValue().getProperty(PageData.PropertyHELP);
        	current.add("").add(Parser.make(
        			parser.getPage(),helpText).parse());
        } else {
            current.childAt(1).putProperty(WikiWord.WITH_EDIT, "true");
            ParsingPage included = option.equals("-setup") || option.equals("-teardown")
                    ? parser.getPage()
                    : parser.getPage().copyForNamedPage(includedPage.getValue());
            current.add("").add(Parser.make(
                            included,
                            includedPage.getValue().getContent())
                            .parse());
            if (option.equals("-setup")) current.evaluateVariables(setUpSymbols, parser.getVariableSource());
        }

      // Remove trailing newline so we do not introduce excessive whitespace in the page.
      if (parser.peek().isType(SymbolType.Newline)) {
        parser.moveNext(1);
      }

      return new Maybe<>(current);
    }

    @Override
    public String toTarget(Translator translator, Symbol symbol) {
        if (symbol.getChildren().size() < 4) {
            return translator.translate(symbol.childAt(2));
        }
        String option = symbol.childAt(0).getContent();
        if (option.equals("-seamless")) {
            return translator.translate(symbol.childAt(3));
        } else if (includeHelpOption.equals(option)) {
        	return translator.translate(symbol.childAt(3));
        } else {
            String collapseState = stateForOption(option, symbol);
            String title = "Included page: "
                    + translator.translate(symbol.childAt(1));
            Collection<String> extraCollapsibleClass =
                    option.equals("-teardown") ? Collections.singleton(TEARDOWN) : Collections.<String>emptySet();
            return Collapsible.generateHtml(collapseState, title, translator.translate(symbol.childAt(3)), extraCollapsibleClass);
        }
    }

    private String stateForOption(String option, Symbol symbol) {
        return ((option.equals("-setup") || option.equals("-teardown")) && symbol.getVariable("COLLAPSE_SETUP", "true").equals("true"))
                || option.equals("-c")
                ? Collapsible.CLOSED
                : "";
    }
}

@@ -155,30 +155,8 @@
 ons;
-%0Aimport java.util.Set;
 %0A%0Apu

Remove unused import