// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace NuGet.Build.Tasks
{
    /// <summary>
    /// Convert .metaproj paths to project paths.
    /// </summary>
    public class GetRestoreSolutionProjectsTask : Task
    {
        private const string MetaProjExtension = ".metaproj";

        /// <summary>
        /// Solution project references.
        /// </summary>
        [Required]
        public ITaskItem[] ProjectReferences { get; set; }

        /// <summary>
        /// Root path used for resolving the absolute project paths.
        /// </summary>
        [Required]
        public string SolutionFilePath { get; set; }

        /// <summary>
        /// Output items
        /// </summary>
        [Output]
        public ITaskItem[] OutputProjectReferences { get; set; }

        public override bool Execute()
        {
            // Log inputs
            var log = new MSBuildLogger(Log);
            log.LogDebug($"(in) ProjectReferences '{string.Join(";", ProjectReferences.Select(p => p.ItemSpec))}'");
            log.LogDebug($"(in) SolutionFilePath '{SolutionFilePath}'");

            var entries = new List<ITaskItem>();
            var parentDirectory = Path.GetDirectoryName(SolutionFilePath);

            foreach (var project in ProjectReferences)
            {
                if (string.IsNullOrEmpty(project.ItemSpec))
                {
                    continue;
                }

                var projectPath = Path.GetFullPath(Path.Combine(parentDirectory, project.ItemSpec));

                // Check for the metaproj extension, this is auto generated by solutions instead of 
                // the actual project path when build order is set. For the purpose of restore 
                // the order is not important so we remove the extension to get the real project path.
                if (projectPath.EndsWith(MetaProjExtension, StringComparison.OrdinalIgnoreCase))
                {
                    // Remove .metaproj from the path.
                    projectPath = projectPath.Substring(0, projectPath.Length - MetaProjExtension.Length);
                }

                // Clone items using the modified path
                var newEntry = new TaskItem(projectPath, project.CloneCustomMetadata());
                entries.Add(newEntry);
            }

            OutputProjectReferences = entries.ToArray();

            return true;
        }
    }
}
