/*
 * Copyright 2016 the original author or authors.
 *
 * 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 de.vorb.platon.integration.pages;

import org.assertj.core.util.Preconditions;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class CommentListPage {

    private final WebDriver webDriver;

    public CommentListPage(WebDriver webDriver) {
        this.webDriver = webDriver;
    }

    public void waitUntilCommentListLoaded() {
        new WebDriverWait(webDriver, 15).until(
                ExpectedConditions.presenceOfElementLocated(By.className("platon-comments")));
    }

    public boolean isCommentFormVisible() {
        return webDriver.findElement(By.className("platon-form")).isDisplayed();
    }

    public boolean isCommentWithIdVisible(long id) {
        final WebElement comment = findCommentById(id);
        return comment.isDisplayed();
    }

    public boolean isCommentWithIdDeleted(long id) {
        final WebElement comment = findCommentById(id);
        final String author = comment.findElement(By.className("platon-author")).getText();
        final String text = comment.findElement(By.className("platon-text")).getText();
        return "[deleted]".equals(author)
                && "[deleted]".equals(text);
    }

    public void replyToComment(long id, String text, String author, String email, String url) {
        final WebElement existingComment = findCommentById(id);
        existingComment.findElement(By.linkText("Reply")).click();

        Preconditions.checkNotNull(text);
        getFirstVisibleChildMatching(existingComment, By.className("platon-form-text")).sendKeys(text);

        if (author != null) {
            getFirstVisibleChildMatching(existingComment, By.className("platon-form-author")).sendKeys(author);
        }

        if (email != null) {
            getFirstVisibleChildMatching(existingComment, By.className("platon-form-email")).sendKeys(email);
        }

        if (url != null) {
            getFirstVisibleChildMatching(existingComment, By.className("platon-form-email")).sendKeys(url);
        }

        getFirstVisibleChildMatching(existingComment, By.cssSelector("form.platon-form")).submit();
    }

    public boolean commentWithIdHasReplies(long id) {

        new WebDriverWait(webDriver, 15).until(
                ExpectedConditions.visibilityOfNestedElementsLocatedBy(findCommentById(id),
                        By.className("platon-comment")));

        return !findCommentById(id).findElements(By.className("platon-comment")).isEmpty();
    }

    private WebElement findCommentById(long id) {
        return webDriver.findElement(By.id("platon-comment-" + id));
    }

    private WebElement getFirstVisibleChildMatching(WebElement parent, By childLocator) {
        return parent.findElements(childLocator).stream()
                .filter(WebElement::isDisplayed)
                .findFirst()
                .orElseThrow(() -> new NullPointerException("No matching element found that is visible"));
    }
}

@@ -804,16 +804,65 @@
 lement;%0A
+import org.openqa.selenium.interactions.Actions;%0A
 import o
@@ -965,16 +965,40 @@
 rWait;%0A%0A
+import java.util.List;%0A%0A
 public c
@@ -2289,32 +2289,60 @@
 l(text);%0A       
+ final WebElement textArea =
  getFirstVisible
@@ -2405,16 +2405,100 @@
 -text%22))
+;%0A        new Actions(webDriver).moveToElement(textArea).perform();%0A        textArea
 .sendKey
@@ -2540,32 +2540,67 @@
 l) %7B%0A           
+ final WebElement authorTextField =
  getFirstVisible
@@ -2665,16 +2665,122 @@
 uthor%22))
+;%0A            new Actions(webDriver).moveToElement(authorTextField).perform();%0A            authorTextField
 .sendKey
@@ -2833,32 +2833,66 @@
 l) %7B%0A           
+ final WebElement emailTextField =
  getFirstVisible
@@ -2948,32 +2948,136 @@
 on-form-email%22))
+;%0A            new Actions(webDriver).moveToElement(emailTextField).perform();%0A            emailTextField
 .sendKeys(email)
@@ -3123,24 +3123,56 @@
 %0A           
+ final WebElement urlTextField =
  getFirstVis
@@ -3240,16 +3240,116 @@
 email%22))
+;%0A            new Actions(webDriver).moveToElement(urlTextField).perform();%0A            urlTextField
 .sendKey
@@ -3740,16 +3740,41 @@
     
-return !
+final List%3CWebElement%3E replies = 
 find
@@ -3837,19 +3837,198 @@
 t%22))
-.isEmpty();
+;%0A%0A        if (!replies.isEmpty()) %7B%0A            new Actions(webDriver).moveToElement(replies.get(0)).perform();%0A            return true;%0A        %7D else %7B%0A            return false;%0A        %7D
 %0A   

Move to relevant areas on the page in ITs