var express = require("express");
var createServer = require("../server/server");
var webdriver = require("selenium-webdriver");
var istanbul = require("istanbul");
var path = require("path");
var fs = require("fs");

var testPort = 52684;
var baseUrl = "http://localhost:" + testPort;
var instrumenter = new istanbul.Instrumenter();
var collector = new istanbul.Collector();
var gatheringCoverage = process.env.running_under_istanbul;
var coverageFilename = "build_artifacts/coverage-e2e.json";

var driver;
var router;
var server;

module.exports.setupDriver = function() {
    driver = new webdriver.Builder().forBrowser("chrome").build();
};

module.exports.setupServer = function(done) {
    router = express.Router();
    if (gatheringCoverage) {
        router.get("/main.js", function(req, res) {
            var absPath = path.join(__dirname, "..", "public", "main.js");
            res.send(instrumenter.instrumentSync(fs.readFileSync("public/main.js", "utf8"), absPath));
        });
    }
    server = createServer(testPort, router, done);
};

module.exports.teardownServer = function(done) {
    server.close(done);
};

module.exports.teardownDriver = function() {
    /*if (gatheringCoverage) {
        driver.executeScript("return __coverage__;").then(function (coverage) {
            collector.add(coverage);
        });
    }*/
    driver.quit();
};

module.exports.reportCoverage = function() {
    if (gatheringCoverage) {
        fs.writeFileSync(coverageFilename, JSON.stringify(collector.getFinalCoverage()), "utf8");
    }
};

module.exports.navigateToSite = function() {
    driver.get(baseUrl);
    driver.sleep(1000);
};

module.exports.getTitleText = function() {
    return driver.findElement(webdriver.By.css("h1")).getText();
};

module.exports.getInputText = function() {
    return driver.findElement(webdriver.By.id("new-todo")).getAttribute("value");
};

module.exports.getErrorText = function() {
    var errorElement = driver.findElement(webdriver.By.id("error"));
    driver.wait(webdriver.until.elementTextContains(errorElement, "Failed"), 5000);
    return errorElement.getText();
};

module.exports.getTodoList = function() {
    var todoListPlaceholder = driver.findElement(webdriver.By.id("todo-list-placeholder"));
    driver.wait(webdriver.until.elementIsNotVisible(todoListPlaceholder), 5000);
    return driver.findElements(webdriver.By.css("#todo-list li"));
};

module.exports.elementExistsById = function(id) {
    return driver.findElement(webdriver.By.id(id)).then(function(arg) {
        return true;
    }, function(err) {
        return false;
    });
};

module.exports.addTodo = function(text) {
    driver.findElement(webdriver.By.id("new-todo")).sendKeys(text);
    driver.findElement(webdriver.By.id("submit-todo")).click();
};

module.exports.deleteTodo = function(id) {
    driver.findElement(webdriver.By.id(id)).click();
};

module.exports.deleteCompleted = function() {
    driver.findElement(webdriver.By.id("clearCompleteButton")).click();
};

module.exports.completeTodo = function(id) {
    driver.findElement(webdriver.By.id(id)).click();
};

module.exports.filterAll = function() {
    driver.findElement(webdriver.By.id("All")).click();
};

module.exports.filterActive = function() {
    driver.findElement(webdriver.By.id("Active")).click();
};

module.exports.filterComplete = function() {
    driver.findElement(webdriver.By.id("Complete")).click();
};

module.exports.pauseTest = function(n) {
    return driver.sleep(n);
};

module.exports.getElementClass = function(element) {
    return element.getAttribute("class");
};

module.exports.getElementStyleById = function(id) {
    return driver.findElement(webdriver.By.id(id)).getAttribute("style");
};

module.exports.getSelectedFilterButton = function() {
    return driver.findElement(webdriver.By.className("button_selected")).getText();
};

module.exports.getCounterMessage = function() {
    return driver.findElement(webdriver.By.id("count-label")).getText();
};

module.exports.setupErrorRoute = function(action, route) {
    if (action === "get") {
        router.get(route, function(req, res) {
            res.sendStatus(500);
        });
    }
    if (action === "post") {
        router.post(route, function(req, res) {
            res.sendStatus(500);
        });
    }
    if (action === "delete") {
        router.delete(route, function(req, res) {
            res.sendStatus(500);
        });
    }
};

@@ -1629,18 +1629,154 @@
 ver.
-sleep(1000
+wait(webdriver.until.elementLocated(webdriver.By.id(%22new-todo%22)),%0A    10000,%0A    %22Could not locate the new-todo element within the time specified%22
 );%0A%7D

modify tests to wait until new-todo element is located on page before running tests