using System;
using System.Text;
using System.Net;
using System.IO;
using System.Security;
using System.Runtime.InteropServices;

namespace memoQSampleCMSConnector
{
    public enum JiraResource
    {
        project,
        issue,
        search
    }

    public class JiraManager
    {
        private string m_BaseUrl;
        private string m_Username;
        private SecureString securePassword; // TODO: Not really used properly yet.

        private string m_Password
        {
            get
            {
                return Marshal.PtrToStringBSTR(Marshal.SecureStringToBSTR(securePassword));
            }
            set
            {
                securePassword = new SecureString();
                foreach (char c in value.ToCharArray())
                    securePassword.AppendChar(c);
            }
        }

        public JiraManager(string baseurl, string username, string password)
        {
            m_BaseUrl = baseurl;
            m_Username = username;
            m_Password = password;
        }

        public string RunQuery(JiraResource resource, string argument = null, string data = null, string method = "GET", string urlExt = null)
        {
            string url = string.Format("{0}{1}", m_BaseUrl, resource.ToString());

            if (urlExt != null)
            {
                url = string.Format("{0}/{1}", url, urlExt);
            }

            if (argument != null)
            {
                // JQL queries can contain spaces, quotes, and other things that must be URL-encoded
                url = Uri.EscapeUriString(string.Format("{0}?{1}", url, argument)).Replace("%20", "+").Replace(",", "%2C");
            }

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.ContentType = "application/json";
            request.Method = method;

            if (data != null)
            {
                using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                {
                    writer.Write(data);
                }
            }

            if (m_Username != null && m_Password != null)
            {
                string base64Credentials = GetEncodedCredentials();
                request.Headers.Add("Authorization", "Basic " + base64Credentials);
            }

            HttpWebResponse response;
            string json;
            StreamReader reader;

            do
            {
                response = request.GetResponse() as HttpWebResponse;
                json = string.Empty;
                using (reader = new StreamReader(response.GetResponseStream()))
                {
                    json = reader.ReadToEnd();
                }

            } while (false);

            return json;
        }

		private string GetEncodedCredentials()
        {
            string mergedCredentials = string.Format("{0}:{1}", m_Username, m_Password);
            byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
            return Convert.ToBase64String(byteCredentials);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                // free managed resources
                if (securePassword != null)
                {
                    securePassword.Dispose();
                    securePassword = null;
                }
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}