using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Configuration;
using System.Net;
using System.IO;

namespace RestApiTest
{
    [TestClass]
    public class TablesTest
    {
        const string CLEANUP_REQUEST = "{\"Query\":\"IF OBJECT_ID('[_TablesTest]') IS NOT NULL DROP TABLE [_TablesTest]\"}";
        const string VERIFY_REQUEST = "{\"Query\":\"SELECT * FROM [_TablesTest] ORDER BY [id]\"}";
        const string VERIFY_RESULT = "id,a,b,c\n0,0.1,0.2,0.3\n1,1.1,1.2,1.3\n2,2.1,2.2,2.3";
        const string TABLES_REQUEST_URI = "/contexts/mydb/tables";
        const string QUERY_REQUEST_URI = "/contexts/mydb/query";

        [TestCleanup]
        public void Cleanup()
        {
            string requestUri = ConfigurationManager.AppSettings["RestApiUri"] + QUERY_REQUEST_URI;
            var request = (HttpWebRequest)WebRequest.Create(requestUri);
            request.Method = "POST";
            request.ContentType = "application/json";
            request.Headers.Add("X-Auth-Token", CredentialsManager.RegisteredUser.Token.Id);
            StreamWriter writer = new StreamWriter(request.GetRequestStream());
            writer.Write(CLEANUP_REQUEST);
            writer.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        }

        [TestMethod]
        [DeploymentItem("data.csv")]
        public void AuthorizedTableUpload()
        {
            AuthorizedLoad();
            VerifyData();
        }

        [TestMethod]
        public void UnauthorizedTableUpload()
        {
            string requestUri = ConfigurationManager.AppSettings["RestApiUri"] + TABLES_REQUEST_URI + "/_TablesTest";
            var request = (HttpWebRequest)WebRequest.Create(requestUri);
            request.Method = "POST";
            request.ContentType = "application/json";
            request.Headers.Add("X-Auth-Token", "_invalid token_");
            StreamWriter writer = new StreamWriter(request.GetRequestStream());
            writer.Write("");
            writer.Close();
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Assert.Fail();
            }
            catch (WebException ex)
            {
                using (HttpWebResponse response = (HttpWebResponse)ex.Response)
                {
                    Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode);
                }
            }
        }

        private void VerifyData()
        {
            string requestUri = ConfigurationManager.AppSettings["RestApiUri"] + QUERY_REQUEST_URI;
            var request = (HttpWebRequest)WebRequest.Create(requestUri);
            request.Method = "POST";
            request.ContentType = "application/json";
            request.Headers.Add("X-Auth-Token", CredentialsManager.RegisteredUser.Token.Id);
            StreamWriter writer = new StreamWriter(request.GetRequestStream());
            writer.Write(VERIFY_REQUEST);
            writer.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
            
            StreamReader reader = new StreamReader(response.GetResponseStream());
            string s = reader.ReadToEnd();
            reader.Close();
            Assert.AreEqual(VERIFY_RESULT, s);
        }

        private void AuthorizedLoad()
        {
            string requestUri = ConfigurationManager.AppSettings["RestApiUri"] + TABLES_REQUEST_URI + "/_TablesTest";
            var request = (HttpWebRequest)WebRequest.Create(requestUri);
            request.Method = "POST";
            request.ContentType = "application/json";
            request.Headers.Add("X-Auth-Token", CredentialsManager.RegisteredUser.Token.Id);
            Stream requestStream = request.GetRequestStream();
            Stream dataStream = new FileStream("data.csv", FileMode.Open);
            dataStream.CopyTo(requestStream);
            requestStream.Close();
            dataStream.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
        }
    }
}
