using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Web.Cors;
using System.Net.Http;
using System.Web.Http.Cors;
using System.Threading;
using System.Threading.Tasks;
using System.Data;
using System.Configuration;

using DataAccess;

namespace RevampApi
{
    /// <summary>
    /// Build policy provider
    /// </summary>
    public class DynamicPolicyProviderFactory : ICorsPolicyProviderFactory
    {
        /// <summary>
        /// Get CORS policy provider
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
        {
            var route = request.GetRouteData();
            var controller = (string)route.Values["controller"];
            var action = (string)route.Values["action"];
            var corsRequestContext = request.GetCorsRequestContext();
            var originRequested = corsRequestContext.Origin;

            var policy = GetPolicyForControllerAndOrigin(originRequested, controller, action);
            
            return new CustomPolicyProvider(policy);
        }

        private CorsPolicy GetPolicyForControllerAndOrigin(string originRequested, string controller, string action)
        {
            // Do database lookup to determine if the controller is allowed for
            // the origin and create CorsPolicy if it is (otherwise return null)
            var policy = new CorsPolicy();

            policy.AllowAnyHeader = true;
            policy.AllowAnyMethod = false;
            policy.AllowAnyOrigin = true;

            //validate origin
            //bool bAllowed = IsOriginAllowed(originRequested, controller, action);
            //if (bAllowed)
            //{
            //    policy.Origins.Add(originRequested);
            //}
            //policy.Origins.Add(originRequested);

            //valid methods
            policy.Methods.Add("OPTIONS");
            policy.Methods.Add("GET");
            policy.Methods.Add("POST");

            return policy;
        }

        private bool IsOriginAllowed(string strOrigin, string strService, string strFunction)
        {
            string strConnectionString = String.Empty;
            bool bAudit = true;

            long lStatusCode = -1;
            string strStatusComment = String.Empty;

            bool bResult = false;

            
            //config settings
            strConnectionString = ConfigurationManager.ConnectionStrings["DBConnString"].ConnectionString;
            bAudit = (ConfigurationManager.AppSettings["AUDIT"] == "1") ? true : false;

            //connect to data source
            CDataConnection cnn = new CDataConnection();
            if (!cnn.Connect(strConnectionString, (int)DataConnectionType.Oracle, bAudit))
            {
                strStatusComment = "Error Connecting to Data Source";
                lStatusCode = 1;
                return false;
            }

            
            //parameter list (BaseMstr.ASPSessionID, BaseMstr.ClientIP, BaseMstr.FXUserID);
            CDataParameterList pList = new CDataParameterList(String.Empty, String.Empty, 0);

            //add params for the DB stored procedure call
            pList.AddInputParameter("pi_vOrigin", strOrigin);
            pList.AddInputParameter("pi_vService", strService);
            pList.AddInputParameter("pi_vFunction", strFunction);

            //
            CDataSet cds = new CDataSet();
            DataSet ds = cds.GetOracleDataSet(cnn,
                                              "PCK_API.ValidateOriginRequestRS",
                                              pList,
                                              out lStatusCode,
                                              out strStatusComment);

            //check response
            if (lStatusCode == 0)
            {
                if (lStatusCode == 0)
                {
                    if (ds != null)
                    {
                        foreach (DataTable table in ds.Tables)
                        {
                            foreach (DataRow row in table.Rows)
                            {
                                if (!row.IsNull("ORIGIN_VALIDATION_RESULT"))
                                {
                                    bResult = row["ORIGIN_VALIDATION_RESULT"].ToString() == "1" ? true : false;
                                    return bResult;
                                }
                            }
                        }
                    }
                }
            }


            //deny access
            return false;

        }
    }
}