using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OptimaJet.Workflow.Core.Entities;
using OptimaJet.Workflow.Core.Persistence;
using Oracle.ManagedDataAccess.Client;

// ReSharper disable once CheckNamespace

namespace OptimaJet.Workflow.Oracle
{
    public class ProcessInstanceTree : DbObject<ProcessInstanceTreeItem>
    {
        public ProcessInstanceTree(string schemaName, int commandTimeout) : base(schemaName, "virtual", commandTimeout)
        {
            DBColumns.AddRange(new[]
            {
                new ColumnInfo {Name = nameof(ProcessInstanceTreeItem.Id), IsKey = true, Type = OracleDbType.Raw},
                new ColumnInfo {Name = nameof(ProcessInstanceTreeItem.ParentProcessId), Type = OracleDbType.Raw},
                new ColumnInfo {Name = nameof(ProcessInstanceTreeItem.RootProcessId), Type = OracleDbType.Raw}, 
                new ColumnInfo {Name = nameof(ProcessInstanceTreeItem.StartingTransition)},
                new ColumnInfo {Name = nameof(ProcessInstanceTreeItem.SubprocessName)},
            });
        }

        public async Task<List<IProcessInstanceTreeItem>> GetProcessTreeItemsByRootProcessId(OracleConnection connection, Guid rootProcessId)
        {
            var workflowProcessInstance = new WorkflowProcessInstance(SchemaName, CommandTimeout);
            
            var builder = new StringBuilder();
            builder.Append("SELECT ");
            builder.Append(nameof(ProcessInstanceTreeItem.Id));
            builder.Append(", ");
            builder.Append(nameof(ProcessInstanceTreeItem.ParentProcessId));
            builder.Append(", ");
            builder.Append(nameof(ProcessInstanceTreeItem.RootProcessId));
            builder.Append(", ");
            builder.Append(nameof(ProcessInstanceTreeItem.StartingTransition));
            builder.Append(", ");
            builder.Append(nameof(ProcessInstanceTreeItem.SubprocessName) );
            builder.Append(" FROM ");
            builder.Append(workflowProcessInstance.ObjectName);
            builder.Append(" WHERE ");
            builder.Append(nameof(ProcessInstanceTreeItem.RootProcessId) );
            builder.Append(" = :rootProcessId");

            var rootProcessIdParameter = new OracleParameter("rootProcessId", OracleDbType.Raw, rootProcessId.ToByteArray(), 
                ParameterDirection.Input);

            return (await SelectAsync(connection, builder.ToString(), rootProcessIdParameter)
                .ConfigureAwait(false)).Cast<IProcessInstanceTreeItem>().ToList();
        }
    }
}
