using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
using Calculator_SeleniumHQ.AcceptanceTests.StepHelpers;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

namespace Calculator_SeleniumHQ.AcceptanceTests.Steps
{
    [Binding]
    public class Calculation
    {
        [Then("the available operators should be \"(.*)\"")]
        public void TheAvailableOperatorsShouldBe(string operators)
        {
            // Arrange
            IOrderedEnumerable<string> availOps = operators.Split(new char[] { ',' }).ToList().OrderBy(o => o);

            // Act
            SelectElement select = new SelectElement(WebBrowser.Current.FindElement(By.Id("operator")));
            IOrderedEnumerable<string> actualOps = select.Options.Select(o => o.Text)
                                                                 .Where(o => !string.IsNullOrWhiteSpace(o))
                                                                 .OrderBy(o => o);
            string strAvailOps = string.Join(",", availOps);
            string strActualOps = string.Join(",", actualOps);

            // Assert
            Assert.AreEqual(strAvailOps, strActualOps,
                string.Format("SelectList was expected to have the options \"{0}\" but instead has the options \"{1}\".",
                    strAvailOps,
                    strActualOps));
        }

        [When("the \"(.*)\" element with id \"(.*)\" contains (.*)")]
        public void TheElementWithIdContainsValue(string element, string id, decimal value)
        {
            // Arrange

            // Act
            IWebElement pageElement = WebBrowser.Current.FindElement(By.Id(id));

            // Assert
            Assert.AreEqual(element.ToLower(), pageElement.TagName.ToLower(), string.Format("Element with id \"{0}\" was expected to be of type \"{1}\", but instead was of type \"{2}\".", id, element.ToLower(), pageElement.TagName.ToLower()));

            // Input the value
            pageElement.SendKeys(value.ToString());
        }

        [When("the \"(.*)\" element with id \"(.*)\" contains \"(.*)\"")]
        public void TheElementWithIdContainsString(string element, string id, string op)
        {
            // Arrange

            // Act
            IWebElement pageElement = WebBrowser.Current.FindElement(By.Id(id));
            SelectElement selElement = new SelectElement(pageElement);
            
            // Assert
            Assert.AreEqual(element.ToLower(), pageElement.TagName.ToLower(), string.Format("Element with id \"{0}\" was expected to be of type \"{1}\", but instead was of type \"{2}\".", id, element.ToLower(), pageElement.TagName.ToLower()));
            
            // Select the operator
            selElement.SelectByText(op);
        }

        [Then("the \"(.*)\" element with id \"(.*)\" should contain (.*)")]
        public void TheElementWithIdShouldContain(string element, string id, decimal result)
        {
            // Arrange

            // Act
            IWebElement pageElement = WebBrowser.Current.FindElement(By.Id(id));

            // Assert
            Assert.AreEqual(element.ToLower(), pageElement.TagName.ToLower(), string.Format("Element with id \"{0}\" was expected to be of type \"{1}\", but instead was of type \"{2}\".", id, element.ToLower(), pageElement.TagName.ToLower()));
            Assert.AreEqual(result.ToString(), pageElement.Text, string.Format("Element with id \"{0}\" was expected to have the value \"{1}\", but instead had the value \"{2}\".", id, result, pageElement.Text));
        }
    }
}
