@using OurUmbraco.Release
@using OurUmbraco.Release.Models
@using Version = System.Version
@inherits Umbraco.Web.Macros.PartialViewMacroPage

@{
    var notesOnly = Request.QueryString["notes"] != null;

    Version fromVersion;
    Version toVersion;

    Version.TryParse(Request.QueryString["from"], out fromVersion);
    Version.TryParse(Request.QueryString["to"], out toVersion);

    // If there's values in the POST (from the form) then those overrule the values in the querystring
    if (Request.Form["from"] != null && Request.Form["to"] != null)
    {
        Version.TryParse(Request.Form["from"], out fromVersion);
        Version.TryParse(Request.Form["to"], out toVersion);
    }

    var sortedVersions = new Dictionary<Version, IPublishedContent>();
    var selectedVersions = new Dictionary<Version, IPublishedContent>();

    foreach (var release in Model.Content.Parent.Children.Where(x => x.GetPropertyValue<string>("releaseStatus") != "Planning" 
                        && x.GetPropertyValue<string>("releaseStatus") != "Unreleased" 
                        && string.IsNullOrWhiteSpace(x.GetPropertyValue<string>("releaseStatus")) == false))
    {
        try
        {
            sortedVersions.Add(new Version(release.Name), release);
        }
        catch (Exception ex)
        {
            <span style="display: none">Couldn't add version @release.Name</span>
        }
    }

    var majorVersionGroups = sortedVersions.GroupBy(x => x.Key.Major).OrderByDescending(x => x.Key);
    var allVersions = new Versions();
    var youTrackVersions = allVersions.GetAggregateVersionsFromFile();

    var newFeatures = 0;
    var breakingChanges = 0;
    var issuesTasks = 0;

    var newFeatureList = new List<AggregateView>();
    var breakingList = new List<AggregateView>();
    var issueList = new List<AggregateView>();

    if (fromVersion != null && toVersion != null && toVersion <= fromVersion)
    {
        <p class="error">Can't compare versions that are equal to each other or where the "to" is lower than the "from".</p>
    }

    // Reset to show the compare between the previous version and the newest available version
    if ((fromVersion == null && toVersion == null) || (toVersion <= fromVersion))
    {
        toVersion = sortedVersions.Last().Key;
        fromVersion = sortedVersions.Skip(sortedVersions.Count - 2).First().Key;
    }

    <form name="compare" method="post">
        <div class="row">
            <div class="col-xs-6 col-sm-4">
                <div class="row">
                    <div class="col-sm-3 titles">From:</div>
                    <div class="col-sm-9">
                        <select name="from">
                            @foreach (var majorVersion in majorVersionGroups)
                            {
                                var versions = majorVersion.OrderByDescending(x => x.Key);
                                <optgroup label="@majorVersion.Key">
                                    @foreach (var version in versions)
                                    {
                                        if (version.Key.ToString() == fromVersion.ToString())
                                        {
                                            <option name="@version.Key" selected="selected" value="@version.Key">@version.Key</option>
                                        }
                                        else
                                        {
                                            <option name="@version.Key" value="@version.Key">@version.Key</option>
                                        }
                                    }
                                </optgroup>
                            }
                        </select>
                    </div>
                </div>
            </div>
            <div class="col-xs-6 col-sm-4">
                <div class="row">
                    <div class="col-sm-3 titles">To:</div>
                    <div class="col-sm-9">
                        <select name="to">
                            @foreach (var majorVersion in majorVersionGroups)
                            {
                                var versions = majorVersion.OrderByDescending(x => x.Key);
                                <optgroup label="@majorVersion.Key">
                                    @foreach (var version in versions)
                                    {
                                        if (version.Key.ToString() == toVersion.ToString())
                                        {
                                            <option name="@version.Key" selected="selected" value="@version.Key">@version.Key</option>
                                        }
                                        else
                                        {
                                            <option name="@version.Key" value="@version.Key">@version.Key</option>
                                        }
                                    }
                                </optgroup>
                            }
                        </select>
                    </div>
                </div>
            </div>
            <div class="col-xs-12 col-sm-4">
                <div class="row">
                    <div class="col-xs-12">
                        <input type="submit" value="Compare" class="button" />
                    </div>
                </div>
            </div>
        </div>
    </form>
    <br />

    if (fromVersion != null && toVersion != null && fromVersion < toVersion)
    {
        foreach (var release in sortedVersions.Where(release => release.Key != fromVersion && (release.Key >= fromVersion) && (release.Key <= toVersion)))
        {
            selectedVersions.Add(release.Key, release.Value);
        }

        foreach (var version in selectedVersions.OrderByDescending(x => x.Key))
        {
            var release = youTrackVersions.FirstOrDefault(x => x.version == version.Key.ToString());

            if (release == null)
            {
                continue;
            }

            var newFeatureIssues = release.issues.Where(x => x.type.ToLowerInvariant().Contains("feature")).ToList();
            newFeatureList.Add(new AggregateView { version = version.Key.ToString(), issues = newFeatureIssues });
            newFeatures += newFeatureIssues.Count;

            var breakingIssues = release.issues.Where(x => x.breaking).ToList();
            breakingList.Add(new AggregateView { version = version.Key.ToString(), issues = breakingIssues });
            breakingChanges += breakingIssues.Count;

            var issueIssues = release.issues.Where(x => x.breaking == false && x.type.ToLowerInvariant().Contains("feature") == false).ToList();
            issueList.Add(new AggregateView { version = version.Key.ToString(), issues = issueIssues });
            issuesTasks += issueIssues.Count;
        }

        <div class="row">
            <div class="col-sm-12 explain">
                <div class="row">
                    <div class="col-xs-12 col-sm-4">
                        <div class="dot big progress">
                            <div class="chart" data-percent="100">
                                <p>@newFeatures</p>
                            </div>
                        </div>
                        <div class="chartDesc">
                            <h3><a href="#newFeatures">New Features</a></h3>
                        </div>
                    </div>
                    <div class="col-xs-12 col-sm-4">
                        <div class="dot big progress">
                            <div class="chart" data-percent="100">
                                <p>@breakingChanges</p>
                            </div>
                        </div>
                        <div class="chartDesc">
                            <h3><a href="#breakingChanges">Breaking Changes</a></h3>
                        </div>
                    </div>
                    <div class="col-xs-12 col-sm-4">
                        <div class="dot big progress">
                            <div class="chart" data-percent="100">
                                <p>@issuesTasks</p>
                            </div>
                        </div>
                        <div class="chartDesc">
                            <h3><a href="#issuesTasks">Issues & Tasks</a></h3>
                        </div>
                    </div>
                </div>
            </div>

            <div class="col-sm-12 statuses">

                @if (notesOnly == false)
                {
                    if (newFeatures > 0)
                    {
                        <div id="newFeatures" class="status features">
                            <h2>New Features</h2>
                            @foreach (var release in newFeatureList.Where(x => x.issues.Any()))
                            {
                                <h3>Features released in version @release.version</h3>
                                foreach (var issue in release.issues)
                                {
                                    <ul>
                                        <li class="@issue.StateIcon()" title="@issue.state">
                                            <a href="http://issues.umbraco.org/issue/@(issue.id)" target="_blank">@issue.id - @issue.title</a>
                                        </li>
                                    </ul>
                                }
                            }
                        </div>
                    }

                    if (breakingChanges > 0)
                    {
                        <div id="breakingChanges" class="status breaking">
                            <h2>Breaking Changes</h2>
                            @foreach (var release in breakingList.Where(x => x.issues.Any()))
                            {
                                <h3>Breaking changes in version @release.version</h3>
                                foreach (var issue in release.issues)
                                {
                                    <ul>
                                        <li class="@issue.StateIcon()" title="@issue.state">
                                            <a href="http://issues.umbraco.org/issue/@(issue.id)" target="_blank">@issue.id - @issue.title</a>
                                        </li>
                                    </ul>
                                }
                            }
                        </div>
                    }

                    if (issuesTasks > 0)
                    {
                        <div id="issuesTasks" class="status issues">
                            <h2>Issues & Tasks</h2>
                            @foreach (var release in issueList.Where(x => x.issues.Any()))
                            {
                                <h3>Issues & Tasks fixed in version @release.version</h3>
                                foreach (var issue in release.issues)
                                {
                                    <ul>
                                        <li class="@issue.StateIcon()" title="@issue.state">
                                            <a href="http://issues.umbraco.org/issue/@(issue.id)" target="_blank">@issue.id - @issue.title</a>
                                        </li>
                                    </ul>
                                }
                            }
                        </div>
                    }
                }

                <div id="issuesTasks" class="status issues">
                    <h2>Release Notes</h2>
                    
                    @if (notesOnly)
                    {
                        <p>
                            What follows is a list of release notes, <a href="@RemoveQueryStringByKey(Request.Url.OriginalString, "notes")" style="text-decoration: underline">want to see the list of related issues?</a>
                        </p>
                    }
                    @foreach (var version in selectedVersions.OrderByDescending(x => x.Key))
                    {
                        <h2>Notes for version @version.Key</h2>
                        @Html.Raw(version.Value.GetPropertyValue<string>("bodyText"))
                    }
                </div>
            </div>
        </div>
    }
}

@functions {

    public static string RemoveQueryStringByKey(string url, string key)
    {
        var uri = new Uri(url);

        // this gets all the query string key value pairs as a collection
        var newQueryString = HttpUtility.ParseQueryString(uri.Query);

        // this removes the key if exists
        newQueryString.Remove(key);

        // this gets the page path from root without QueryString
        string pagePathWithoutQueryString = uri.GetLeftPart(UriPartial.Path);

        return newQueryString.Count > 0
            ? String.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
            : pagePathWithoutQueryString;
    }

}