using System;
using System.Management.Automation;

namespace PSInfisicalAPI.Cmdlets
{
    [Cmdlet(VerbsCommon.Get, "InfisicalEnvironmentVariable")]
    [OutputType(typeof(string))]
    public sealed class GetInfisicalEnvironmentVariableCmdlet : InfisicalCmdletBase
    {
        private const string Component = "Get-InfisicalEnvironmentVariable";

        private static readonly EnvironmentVariableTarget[] TargetOrder = new[]
        {
            EnvironmentVariableTarget.Process,
            EnvironmentVariableTarget.User,
            EnvironmentVariableTarget.Machine
        };

        [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
        [ValidateNotNullOrEmpty]
        public string Name { get; set; }

        [Parameter(Position = 1)]
        public EnvironmentVariableTarget? Scope { get; set; }

        protected override void ProcessRecord()
        {
            EnvironmentVariableTarget[] targets = Scope.HasValue ? new[] { Scope.Value } : TargetOrder;

            foreach (EnvironmentVariableTarget target in targets)
            {
                Logger.Verbose(Component, string.Concat("Searching ", target.ToString(), " scope for environment variable '", Name, "'."));

                string value;
                try
                {
                    value = Environment.GetEnvironmentVariable(Name, target);
                }
                catch (Exception exception)
                {
                    Logger.Verbose(Component, string.Concat("Failed to read ", target.ToString(), " scope for environment variable '", Name, "': ", exception.Message));
                    continue;
                }

                if (!string.IsNullOrEmpty(value))
                {
                    Logger.Information(Component, string.Concat("Found environment variable '", Name, "' in ", target.ToString(), " scope."));
                    WriteObject(value);
                    return;
                }
            }

            string scopeDescription = Scope.HasValue ? string.Concat(Scope.Value.ToString(), " scope") : "Process, User, or Machine scope";
            Logger.Information(Component, string.Concat("Environment variable '", Name, "' was not found in ", scopeDescription, "."));
        }
    }
}
