using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Rename;
using Microsoft.CodeAnalysis.Text;

namespace IfAnalyzer
{
	[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(IfAnalyzerCodeFixProvider)), Shared]
	public class IfAnalyzerCodeFixProvider : CodeFixProvider
	{
		private const string title = "Fix my if";

		public sealed override ImmutableArray<string> FixableDiagnosticIds
		{
			get { return ImmutableArray.Create(IfAnalyzerAnalyzer.DiagnosticId); }
		}

		public sealed override FixAllProvider GetFixAllProvider()
		{
			return WellKnownFixAllProviders.BatchFixer;
		}

		public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
		{
			var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

			var diagnostic = context.Diagnostics.First();
			var diagnosticSpan = diagnostic.Location.SourceSpan;

			var statement = (StatementSyntax)root.FindNode(diagnosticSpan);

			context.RegisterCodeFix(
				CodeAction.Create(
					title: title,
					createChangedDocument: c => FixMyif(context.Document, statement, c),
					equivalenceKey: title),
				diagnostic);
		}

		private async Task<Document> FixMyif(Document document, StatementSyntax statementSyntax, CancellationToken cancellationToken)
		{
			var root = await document.GetSyntaxRootAsync(cancellationToken);
			root = root.ReplaceNode(statementSyntax, SyntaxFactory.Block(statementSyntax));
			return document.WithSyntaxRoot(root);
		}
	}
}
