using System;
using System.Collections.Specialized;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using HtmlAgilityPack;


namespace Crawler
{
    public class Crawler : ICrawler
    {
        private bool IsUserAuthenticated { get; set; }
        private string _cookies = string.Empty;

        private Settings Settings { get; set; }

        public Crawler(Settings settings)
        {
            this.Settings = settings;
        }

        public bool Login(string username, string password)
        {
            var postData = new NameValueCollection();
            postData.Add("USER", username);
            postData.Add("PWD", password);

            string postdata = string.Empty;
            var items = postData.AllKeys.SelectMany(postData.GetValues, (k, v) => new { key = k, value = v });

            items.ToList().ForEach(p =>
            {
                postdata += string.Format("{0}={1}&", p.key, p.value);
            });

            string result = string.Empty;
            Post(this.Settings.ValidateLogin, postdata, out result);

            return IsUserAuthenticated;
        }

        public bool GetEmail(Uri url)
        {
            bool logAgain = false;
            string text = string.Empty;
            string adreference = string.Empty;
            var queryString = string.Join(string.Empty, url.ToString().Split('?').Skip(1));
            adreference = !string.IsNullOrEmpty(queryString) ? queryString.Split('=')[1] : url.Segments[1].Trim('/');

            string _url = string.Format(this.Settings.GetEmailTemplate, adreference);
            string result;
            this.Post(new Uri(_url), queryString, out result);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(result);
            if (htmlDoc.DocumentNode.SelectSingleNode("//a") == null) {
                if (htmlDoc.DocumentNode.InnerHtml.IndexOf("captcha") != -1)
                {
                    logAgain = true;
                    text = "Error - Maximum attempts exceeded";
                }
                //return "Error - Maximum attempts exceeded";
                else
                    //return "Error - No email present";
                    text = "Error - Maximum attempts exceeded";
            }
            else
                text = htmlDoc.DocumentNode.SelectSingleNode("//a").InnerText;

            Console.WriteLine(">> Result: {0}", text);
            Console.WriteLine("");
            return logAgain;
        }

        //POST Requests
        public void Post(Uri url, string postdata, out string result)
        {
            var postdataarray = Encoding.UTF8.GetBytes(postdata);
            var myReq = (HttpWebRequest)WebRequest.Create(url.ToString());

            myReq.AllowAutoRedirect = false;
            myReq.Method = "POST";

            if (!IsUserAuthenticated)
                myReq.Referer = this.Settings.ReferUrl.ToString();

            myReq.Headers["Cookie"] = _cookies;
            myReq.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36";
            myReq.ContentType = "application/x-www-form-urlencoded";
            myReq.ContentLength = postdataarray.Length;

            Stream dataStream = myReq.GetRequestStream();
            dataStream.Write(postdataarray, 0, postdataarray.Length);
            dataStream.Close();

            WebResponse response = myReq.GetResponse();

            var sr = new StreamReader(response.GetResponseStream());
            result = sr.ReadToEnd();
            //Get Cookies
            _cookies += response.Headers["Set-Cookie"];
            var location = response.Headers["Location"];

            if (!IsUserAuthenticated)
            {
                if (location.StartsWith("invalido.asp") || location.StartsWith("android"))
                    this.IsUserAuthenticated = false;
                else 
                    this.IsUserAuthenticated = true;
            }

            response.Close();
        }
    }
}
