using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Caliburn.Micro;
using FDOT.GIS.Client.Commands;
using FDOT.GIS.Client.Domain;

namespace FDOT.GIS.Framework.Samples.Commands
{
    [Export(typeof(IScriptableCommand))]
    public class IdentifyCommand : ScriptableCommand<IdentifyCommandParameters>
    {
        public IEnumerable<Feature> Result { get; internal set; }

        /// <summary>
        /// A string identifier for this command.
        /// </summary> 
        public override string CommandVerb
        {
            get { return "ident"; }
        }

        /// <summary>
        /// Executes the command with the specified <see cref="IdentifyCommandParameters"/>.
        /// </summary>
        /// <param name="parameters"></param>
        public override void Execute(IdentifyCommandParameters parameters)
        {
            var executionContext = new ActionExecutionContext();
            Coroutine.BeginExecute(GetWorkflow(parameters).GetEnumerator(), executionContext, Complete);
        }

        protected IEnumerable<IResult> GetWorkflow(IdentifyCommandParameters parameters)
        {
            Log.Info("Executing idenity for FeatureType [{0}].", parameters.FeatureTypeName);

            Identify identify = new Identify(parameters.Geometry, parameters.FeatureTypeName);
            yield return identify;

            var results = identify.Result;
            this.Result = results.Where(x => x.Key.Name.Equals(parameters.FeatureTypeName, StringComparison.CurrentCultureIgnoreCase)).SelectMany(x => x.Value);
            Log.Info("Identify found [{0}] Features.", Result.Count());
        }

        private void Complete(object sender, ResultCompletionEventArgs e)
        {
            if (e.Error != null)
                Failure(e.Error);
            else
                Success(Result);
        }
    }

    public class IdentifyCommandParameters
    {
        public DataContracts.Geometry Geometry { get; set; }
        public string FeatureTypeName { get; set; }
    }
}
