using System;
using Pervasive.Data.SqlClient;

namespace AdoNetCore2_0ProviderTest
{
    class Program
    {
        static int Main(string[] args)
        {
            int returnCode = 0;
            try
            {
                int numParams = 0;
                string cmdLine = "";
                string psqlDbConn = "";
                string sqlCommand = "";

                // Get the full command line.
                foreach (string s in args)
                {
                    cmdLine = cmdLine + " " + s;
                }
                cmdLine = cmdLine.Trim();
                numParams = args.Length;

                // Verify all the remaining required parameters were specified.
                if (!ParamsAreValid(cmdLine.ToLower(), numParams))
                {
                    Console.WriteLine("Return: {0}", -1);
                    return -1;
                }

                // Process the command line to get the values specified for each parameter.
                for (int i = 0; i < args.Length; i++)
                {
                    switch (args[i].ToLower())
                    {
                        case "-connection":
                            psqlDbConn = args[i + 1];
                            Console.WriteLine("...PSQL connection string: \"{0}\"", psqlDbConn);
                            break;
                        case "-sql":
                            sqlCommand = args[i + 1];
                            Console.WriteLine("...SQL statement to run: \"{0}\"", sqlCommand);
                            break;
                        default:
                            break;
                    }
                }

                // PSQL Connection
                PsqlConnection Conn = new PsqlConnection(psqlDbConn);
                try
                {
                    Conn.Open();

                    // PsqlCommand
                    PsqlCommand DBCmd = new PsqlCommand(sqlCommand, Conn);
                    try
                    {
                        // Call ExecuteReader on the command object
                        using (PsqlDataReader dataReader = DBCmd.ExecuteReader())
                        {
                            int numFields = dataReader.FieldCount;
                            string row = "";
                            while (dataReader.Read())
                            {
                                for (int f = 0; f < numFields; f++)
                                {
                                    if (f != numFields - 1)
                                    {
                                        row = row + $"{dataReader[f]}" + "\t";
                                    }
                                    else
                                    {
                                        row = row + $"{dataReader[f]}";
                                    }
                                }
                                Console.Out.NewLine = "\r";
                                Console.WriteLine("\t{0}", row);
                                row = "";
                            }
                            dataReader.Close();
                        }
                    }
                    catch (PsqlException ex)
                    {
                        returnCode = ex.Number;
                        Console.WriteLine("...PsqlException error {0}: {1}", returnCode, ex.Message);
                        return returnCode;
                    }
                    catch (Exception ex)
                    {
                        returnCode = ex.HResult;
                        Console.WriteLine("...Error {0}: {1}", returnCode, ex.Message);
                        return returnCode;
                    }
                }
                catch (PsqlException ex)
                {
                    returnCode = ex.Number;
                    Console.WriteLine("...PsqlConnection.Open() error {0}: {1}", returnCode, ex.Message);
                }
                catch (Exception ex)
                {
                    returnCode = ex.HResult;
                    Console.WriteLine("...Error {0}: {1}", returnCode, ex.Message);
                }

                // Close the connection.
                Conn.Close();

                Console.Out.NewLine = "\r\n";
                return returnCode;
            }
            catch (PsqlException ex)
            {
                returnCode = ex.Number;
                Console.WriteLine("...PsqlException error {0}: {1}", returnCode, ex.Message);
                return returnCode;
            }
            catch (Exception ex)
            {
                returnCode = ex.HResult;
                Console.WriteLine("...Error {0}: {1}", returnCode, ex.Message);
                return returnCode;
            }
            finally
            {
                Console.WriteLine("Return: {0}", returnCode);
            }
        }

        private static Boolean ParamsAreValid(string strParams, int numParams)
        {
            const string SYNTAX = "\n\nSyntax:\n\n    AdoNetStandard2_0Test.dll -connection \"connection string\" -sql \"SQL command\"\n";
            int numParamsReq = 4;

            try
            {
                // Verify the correct number of required parameters was specified.
                if (numParams != numParamsReq)
                {
                    Console.WriteLine("{0} parameters were specified. You must specify all required parameters!" + SYNTAX, numParams);
                    return false;
                }

                // Verify each required parameter was specified.
                if (!strParams.Contains("-connection"))
                {
                    Console.WriteLine("You must specify a connection string!" + SYNTAX);
                    return false;
                }
                if (!strParams.Contains("-sql"))
                {
                    Console.WriteLine("You must specify a SQL statement to be executed!" + SYNTAX);
                    return false;
                }

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("...Error {0}: {1}", ex.HResult, ex.Message);
                return false;
            }
        }
    }
}
