using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Data.SqlClient;
using System.Web.Configuration;

using net.ivoa.data;
using net.ivoa.VOTable;

using edu.jhu.Cas.Util;
using edu.jhu.Cas.Jobs;
using edu.jhu.Cas.Users;

namespace net.ivoa.tools {
    /// <summary>
    /// Summary description for TableImport.
    /// </summary>
    public class TableImport : System.Web.UI.Page {
        protected bool doSigma = false, enableFormatType = false, showinit = true;
        protected long MaxSize;
        protected string message;
        private int DataType, ImportType, FormatType, DataFormat;
        private string DataBoxText, FTPBoxText;
        protected HtmlInputFile httpBox;
        private double sigma;
        protected double estSize;
        protected string separator;
        protected short step;
        protected long rowsLoaded;
        protected string totalTime, tableName;
        protected string[] tables;
        protected long wsid;
        protected bool newTable = false;
        //protected const long MAX_PASTE_CHARS = 2000, MAX_VOTABLE = 1024 * 1024, MAX_DATASET = 5 * 1024 * 1024;
        protected long MAX_PASTE_CHARS = long.Parse(ConfigurationManager.AppSettings["MAX_PASTE_CHARS"]);
        protected long MAX_DATASET = long.Parse(ConfigurationManager.AppSettings["MAX_DATASET"]);

        private void UploadWrapper(DataWrapper dw) {
            string cstring = (new CasUsers()).MyDBServerObject(wsid).ConnectionString;
            SqlCommand com = new SqlCommand();
            com.Connection = new SqlConnection(cstring);
            com.Connection.Open();
            try {
                WholeTableUpload.LoadDataWrapper(dw, com, tableName, newTable);
            } finally {
                com.Connection.Close();
                com.Connection.Dispose();
            }
        }
        override protected void OnInit(EventArgs E) {
            //edu.jhu.Cas.Web.WebUtils.CheckLoggedIn(Session, Response);
            edu.jhu.Cas.Web.WebUtils.CheckLoggedIn(Session, Response, Request);
            HttpRuntimeSection htrs = (HttpRuntimeSection)ConfigurationManager.GetSection("system.web/httpRuntime");
            MaxSize = Math.Min(htrs.MaxRequestLength, MAX_DATASET);
            //MaxSize = MAX_DATASET;
            wsid = (long)Session["USER"];
            MyDBJobs mjs = new MyDBJobs();
            tables = mjs.Tables(wsid);

            message = Request.Params["message"];
            if (Request.Params["NameBox"] != null && Request.Params["NameBox"] != "")
                tableName = Request.Params["NameBox"];
            else
                tableName = edu.jhu.Cas.Web.WebUtils.GetUniqueTableName(wsid);
            try {
                DataType = Request.Params["DataType"] != null ? int.Parse(Request.Params["DataType"]) : -1;
                FormatType = Request.Params["formatType"] != null ? int.Parse(Request.Params["formatType"]) : 0;
                DataFormat = Request.Params["DataFormat"] != null ? int.Parse(Request.Params["DataFormat"]) : 0;
                ImportType = Request.Params["ImportType"] != null ? int.Parse(Request.Params["importType"]) : 0;
                DataBoxText = Request.Params["DataBox"];
                FTPBoxText = Request.Params["ftpBox"];
                if (Request.Params["tableTypeDDL"] != null)
                    newTable = int.Parse(Request.Params["tableTypeDDL"]) == 0;
                if (!newTable && Request.Params["DataType"] != null)
                    tableName = Request.Params["tnameDDL"];
                sigma = Request.Params["sigmaBox"] != null && Request.Params["sigmaBox"].Length > 0 ? double.Parse(Request.Params["sigmaBox"]) : -1;
            } catch (FormatException fe) {
                message = fe.Message;
                return;
            }
            try {
                if (Request.Params["DataType"] != null) {
                    Import();
                    tables = mjs.Tables(wsid);
                    tableName = edu.jhu.Cas.Web.WebUtils.GetUniqueTableName(wsid);
                }
            } catch (Exception e) {
                message = e.ToString();
            }
        }
        protected void Import() {
            try {
                string name = tableName;
                if (name.IndexOf(".") > -1 || name.IndexOf(" ") > -1 || name.IndexOf(",") > -1)
                    throw new Exception("Please do not use the following characters in your table name: '.',',' or ' '");
                if (name == null || name.Length == 0)
                    throw new Exception("You must provide a table name.");
                name = name.Trim();
                bool tableExists = (new MyDBJobs()).MyDBTableExists(wsid, name);
                string data = null;
                if (ImportType == 0) {
                    data = DataBoxText;
                    if (data != null) data = data.Trim(new char[] { ' ', '\t', '\r', '\n' });
                    if (data.Length > MAX_PASTE_CHARS) throw new Exception("The pasted data received is too large and will not be processed.");
                } else if (ImportType == 1) {
                    //long sizeLimit = (DataType == 0) ? MaxSize : MAX_DATASET;
                    long sizeLimit = MaxSize;
                    if (httpBox.PostedFile.ContentLength > sizeLimit) throw new Exception("This file is " +
                        (httpBox.PostedFile.ContentLength / 1024) + " kB but the maximum size for this datatype is " + sizeLimit / 1024 + " kB.  Import halted.");
                    data = (new StreamReader(httpBox.PostedFile.InputStream)).ReadToEnd();
                }
                switch (DataType) {
                    case 0://CSV
                        TextReader tr;
                        if (ImportType == 1) {
                            if (httpBox.PostedFile.FileName == null || httpBox.PostedFile.FileName == "") throw new Exception("Please select a file.");
                        }
                        tr = new StringReader(data);
                        DateTime ts = DateTime.Now;
                        using (CSVDataReader csvdr = new CSVDataReader(tr))
                            csvdr.UploadTo((new CasUsers()).MyDBServerObject(wsid).ConnectionString, name, tableExists);
                        message = "Succesfully uploaded data into " + name + ".  Total time: " + (DateTime.Now - ts).TotalSeconds + " seconds";
                        break;
                    case 1://VOTABLE
                        XmlTextReader reader = new XmlTextReader(new StringReader(data));
                        try {
                            XmlSerializer serializer = new XmlSerializer(typeof(VOTABLE));
                            VOTABLE vot = (VOTABLE)serializer.Deserialize(reader);
                            try {
                                TABLEDATA d = vot.RESOURCE[0].TABLE[0].DATA.Item as TABLEDATA;
                                if (d.TR.Length < 1) throw new Exception("This votable is empty.");
                            } catch { throw new Exception("Unknown error deserializing VOTABLE"); }
                            UploadWrapper(WrapperFactory.GetDataWrapper(vot));
                        } catch {
                            // ok try the lax parser 
                            reader = new XmlTextReader(new StringReader(data));
                            LaxVotableParser lp = new LaxVotableParser(reader);
                            DataSet ds = lp.readAsDataSet();
                            UploadWrapper(WrapperFactory.GetDataWrapper(ds));
                        }
                        message = "VOTABLE Table successfully imported as " + name;
                        break;
                    case 2://dataset
                        XmlTextReader reader2 = new XmlTextReader(new StringReader(data));
                        XmlSerializer serializer2 = new XmlSerializer(typeof(DataSet));
                        DataSet votds = (DataSet)serializer2.Deserialize(reader2);
                        UploadWrapper(WrapperFactory.GetDataWrapper(votds));
                        message = "DataSet table successfully imported as " + name;
                        break;
                }
                (new CasJobs()).SubmitShortJob(wsid, SYSTEM.TAB_IMPORT_QRY_PREF + name + "'", "mydb", SYSTEM.TAB_IMPORT_MESSAGE, 0);
            } catch (Exception e) {
                message = e.Message;
                //message = e.ToString(); 
            }
        }
    }
}