package org.mozilla.javascript.tests.commentspr465;

import org.junit.Assert;
import org.junit.Test;
import org.mozilla.javascript.Node;
import org.mozilla.javascript.Token;
import org.mozilla.javascript.ast.AstNode;
import org.mozilla.javascript.ast.Comment;
import org.mozilla.javascript.ast.FunctionNode;
import org.mozilla.javascript.ast.IfStatement;

/**
 * @author ravik
 * @@since 08/08/18 12:01 PM
 */
public class IfCommentsTest {

    @Test
    public void inlineCommentsForIf() {
        String inputStr = "function f1() {\n" +
                "// alert(type);\n" +
                "if ($scope.disableEdit) // if comment\n" +
                "    $scope.type = ''; //Dont show\n" +
                "else //else\n" +
                "    $scope.type = type;\n" +
                "//abcdef\n" +
                "}";

        AstNode scriptRoot = CommentsTestUtils.getRhinoASTRootNode(inputStr, "ifelse1", null, null);

        FunctionNode funcDef = (FunctionNode) scriptRoot.getFirstChild();
        Node comm1Node = funcDef.getBody().getFirstChild();
        Assert.assertEquals(Token.COMMENT, comm1Node.getType());

        IfStatement ifSt = (IfStatement) comm1Node.getNext();
        AstNode ifInlineComm = ifSt.getInlineComment();
        Assert.assertNotNull(ifInlineComm);
        Assert.assertEquals("// if comment", ((Comment) ifInlineComm).getValue());

        AstNode thenPartNode = ifSt.getThenPart();
        Assert.assertNotNull(thenPartNode.getInlineComment());
        Assert.assertEquals("//Dont show", ((Comment) thenPartNode.getInlineComment()).getValue());

        Assert.assertNotNull(ifSt.getElseKeyWordInlineComment());
        Assert.assertEquals("//else", ((Comment) ifSt.getElseKeyWordInlineComment()).getValue());

        Node comm2Node = ifSt.getNext();
        Assert.assertEquals(Token.COMMENT, comm2Node.getType());
    }

    @Test
    public void blockCommentinElse() {
        String inputStr = "function f1() {\n" +
                "if(x == 8)\n" +
                "    y = 9;\n" +
                "else //test else\n" +
                "{ //else part\n" +
                "    u = 9 + 10;\n" +
                "} //7800\n" +
                "//9034\n" +
                "}";

        AstNode scriptRoot = CommentsTestUtils.getRhinoASTRootNode(inputStr, "ifelse2", null, null);
        FunctionNode funcDef = (FunctionNode) scriptRoot.getFirstChild();

        IfStatement ifSt = (IfStatement) funcDef.getBody().getFirstChild();
        Assert.assertNotNull(ifSt.getElseKeyWordInlineComment());
        Assert.assertEquals("//test else", ((Comment) ifSt.getElseKeyWordInlineComment()).getValue());

        AstNode elseNode = ifSt.getElsePart();
        Assert.assertEquals(Token.BLOCK, elseNode.getType());
        Node comm1Node = elseNode.getFirstChild();
        Assert.assertEquals(Token.COMMENT, comm1Node.getType());
        Assert.assertEquals("//else part", ((Comment) comm1Node).getValue());

        Node comm2Node = ifSt.getNext();
        Assert.assertEquals(Token.COMMENT, comm2Node.getType());
        Assert.assertEquals("//7800", ((Comment) comm2Node).getValue());

        Node comm3Node = comm2Node.getNext();
        Assert.assertEquals(Token.COMMENT, comm3Node.getType());
        Assert.assertEquals("//9034", ((Comment) comm3Node).getValue());
    }

    @Test
    public void commentInbetweenIfElse() {
        String inputStr = "function f1() {\n" +
                "if(a == 3) {\n" +
                "    var x = 4;\n" +
                "} \n" +
                "//end of if\n" +
                "else {\n" +
                "    var x = 4\n" +
                "}\n" +
                "}";

        String outputStr = "if (a == 3) {\n" +
                "  var x = 4;\n" +
                "} else {\n" +
                "  var x = 4;\n" +
                "}";
        AstNode scriptRoot = CommentsTestUtils.getRhinoASTRootNode(inputStr, "ifelse3", null, null);
        FunctionNode funcDef = (FunctionNode) scriptRoot.getFirstChild();
        IfStatement ifSt = (IfStatement) funcDef.getBody().getFirstChild();
        Assert.assertEquals(outputStr.trim(), ifSt.toSource().trim());
    }

    @Test
    public void commentsInElseIf() {
        String inputStr = "function f1() {\n" +
                "if(u == 8) //if 2\n" +
                "    x = 6;   //then 2\n" +
                "else if (y == 8)//else if 2\n" +
                "    o = 0;\n" +
                "else  //else 2\n" +
                "    u = 9;  //elsepart 2\n" +
                "// xysdflj ljk\n" +
                "//test\n" +
                "k = 0 + 8;\n" +
                "}";

        AstNode scriptRoot = CommentsTestUtils.getRhinoASTRootNode(inputStr, "ifelse4", null, null);
        FunctionNode funcDef = (FunctionNode) scriptRoot.getFirstChild();

        IfStatement ifSt = (IfStatement) funcDef.getBody().getFirstChild();
        AstNode ifInlineComm = ifSt.getInlineComment();
        Assert.assertNotNull(ifInlineComm);
        Assert.assertEquals("//if 2", ((Comment) ifInlineComm).getValue());

        IfStatement elsePartIfSt = (IfStatement) ifSt.getElsePart();
        AstNode elseIfInlineComm = elsePartIfSt.getInlineComment();
        Assert.assertNotNull(elseIfInlineComm);
        Assert.assertEquals("//else if 2", ((Comment) elseIfInlineComm).getValue());

        Assert.assertNotNull(elsePartIfSt.getElseKeyWordInlineComment());
        Assert.assertEquals("//else 2", ((Comment) elsePartIfSt.getElseKeyWordInlineComment()).getValue());

        AstNode elseNode = elsePartIfSt.getElsePart();
        Assert.assertEquals("//elsepart 2", ((Comment) elseNode.getInlineComment()).getValue());

        Node comm2Node = ifSt.getNext();
        Assert.assertEquals(Token.COMMENT, comm2Node.getType());
        Assert.assertEquals("// xysdflj ljk", ((Comment) comm2Node).getValue());

        Node comm3Node = comm2Node.getNext();
        Assert.assertEquals(Token.COMMENT, comm3Node.getType());
        Assert.assertEquals("//test", ((Comment) comm3Node).getValue());
    }
}
