/*
 * DrFx - FxCop Report Translator and Visualizer.
 * Copyright (C) 2010 Sasa Yuan
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */



using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace Sasa.QualityTools.DrFx.Core.Tests.Integration
{
    /// <summary>
    /// The integration test class for <see cref=" Sasa.QualityTools.DrFx.Core.FxCopProcessGenerator"/>.
    /// </summary>
    [TestFixture]
    public class FxCopProcessGeneratorTest
    {
        /// <summary>
        /// Prepares the test environment.
        /// This method creates following directories and files
        /// 
        /// WORK_DIR/
        /// +-- FxCopCmd.exe
        /// +-- asm1.dll
        /// +-- asm2.dll
        /// +-- asm3.dll
        /// +-- report.xml
        /// +-- fxcop-1.36_0/
        /// |   `-- FxCopCmd.exe
        /// +-- fxcop-1.36_1/
        /// |   `-- Rules/
        /// `-- fxcop-1.36_2/
        ///     +-- Rules/
        ///     `-- FxCopCmd.exe
        /// </summary>
        [TestFixtureSetUp]
        public void SetUpFixture()
        {
            File.Create("FxCopCmd.exe").Close();
            File.Create("asm1.dll").Close();
            File.Create("asm2.dll").Close();
            File.Create("asm3.dll").Close();
            File.Create("report.xml").Close();
            Directory.CreateDirectory("fxcop-1.36_0");
            File.Create("fxcop-1.36_0\\FxCopCmd.exe").Close();
            Directory.CreateDirectory("fxcop-1.36_1");
            Directory.CreateDirectory("fxcop-1.36_1\\Rules");
            Directory.CreateDirectory("fxcop-1.36_2");
            Directory.CreateDirectory("fxcop-1.36_2\\Rules");
            File.Create("fxcop-1.36_2\\FxCopCmd.exe").Close();
        }

        /// <summary>
        /// Cleans up the test environment.
        /// This method removes all directories and files that are created by SetUpFixture.
        /// </summary>
        [TestFixtureTearDown]
        public void TearDownFixture()
        {
            Directory.Delete("fxcop-1.36_2", true);
            Directory.Delete("fxcop-1.36_1", true);
            Directory.Delete("fxcop-1.36_0", true);
            File.Delete("report.xml");
            File.Delete("asm3.dll");
            File.Delete("asm2.dll");
            File.Delete("asm1.dll");
            File.Delete("FxCopCmd.exe");
        }

        /// <summary>
        /// Tests that StartInfo of generated process object was setup correctly.
        /// </summary>
        [Test]
        public void TestStartInfoOfGeneratedProcess()
        {
            FxCopProcessConfiguration configuration = new FxCopProcessConfiguration();
            configuration.TargetFiles.Add("asm1.dll");
            configuration.FxCopInstallDirectory = "fxcop-1.36_2";
            Process process = FxCopProcessGenerator.GenerateFxCopCmdProcess(configuration);
            Assert.AreEqual(@"""fxcop-1.36_2\FxCopCmd.exe""", process.StartInfo.FileName);
            Assert.AreEqual(@"/c /o:""codeanalysisreport.xml"" /f:""asm1.dll"" /r:""fxcop-1.36_2\Rules""", process.StartInfo.Arguments);
        }

        /// <summary>
        /// Tests that target files valication works correctly.
        /// </summary>
        /// <param name="files">The analysis target files that was separated by camma.</param>
        [TestCase("", ExpectedException = typeof(ValidationException))]
        [TestCase("notexist.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_0", ExpectedException = typeof(ValidationException))]
        [TestCase("asm1.dll,notexist.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_0,asm1.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("asm1.dll")]
        [TestCase("asm1.dll,asm2.dll,asm3.dll")]
        public void TestValidateTargetFiles(string files)
        {
            FxCopProcessConfiguration configuration = new FxCopProcessConfiguration();
            foreach (string file in files.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries))
            {
                configuration.TargetFiles.Add(file);
            }
            FxCopProcessGenerator.ValidateTargetFiles(configuration);
        }

        /// <summary>
        /// Tests that output file validation works correctly.
        /// </summary>
        /// <param name="files">The output files that was separated by camma.</param>
        [TestCase("notexist\\report.xml", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_0", ExpectedException = typeof(ValidationException))]
        [TestCase("report.xml,fxcop-1.36_0", ExpectedException = typeof(ValidationException))]
        [TestCase("")]
        [TestCase("report.xml")]
        [TestCase("notexist\\report.xml,report.xmll")]
        [TestCase("asm1.dll,asm2.dll,asm3.dll,report.xml")]
        public void TestValidateOutputFile(string files)
        {
            FxCopProcessConfiguration configuration = new FxCopProcessConfiguration();
            foreach (string file in files.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries))
            {
                configuration.OutputFile = file;
            }
            FxCopProcessGenerator.ValidateOutputFile(configuration);
        }

        /// <summary>
        /// Tests that rule files validation works correctly.
        /// </summary>
        /// <param name="files">The analysis rule files that was separated by camma.</param>
        [TestCase("notexist.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_0", ExpectedException = typeof(ValidationException))]
        [TestCase("asm1.dll,notexist.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_0,asm1.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("")]
        [TestCase("asm1.dll")]
        [TestCase("asm1.dll,asm2.dll,asm3.dll")]
        public void TestValidateRuleFiles(string files)
        {
            FxCopProcessConfiguration configuration = new FxCopProcessConfiguration();
            foreach (string file in files.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries))
            {
                configuration.RuleFiles.Add(file);
            }
            FxCopProcessGenerator.ValidateRuleFiles(configuration);
        }

        /// <summary>
        /// Tests that dependecy directories validation works correctly.
        /// </summary>
        /// <param name="directories">The dependency directories that was separated by camma.</param>
        [TestCase("notexist", ExpectedException = typeof(ValidationException))]
        [TestCase("asm1.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("notexist,fxcop-1.36_0", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_0,asm1.dll", ExpectedException = typeof(ValidationException))]
        [TestCase("")]
        [TestCase("fxcop-1.36_0")]
        [TestCase("fxcop-1.36_0,fxcop-1.36_1,fxcop-1.36_2")]
        public void TestValidateDependencyDirectories(string directories)
        {
            FxCopProcessConfiguration configuration = new FxCopProcessConfiguration();
            foreach (string directory in directories.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries))
            {
                configuration.DependencyDirectories.Add(directory);
            }
            FxCopProcessGenerator.ValidateDependencyDirectories(configuration);
        }

        /// <summary>
        /// Tests that FxCop install directory validation works correctly.
        /// </summary>
        /// <param name="directory">The directory that is set FxCopInstallDirectory before calling testee.</param>
        [TestCase("fxcop-1.36", ExpectedException = typeof(ValidationException))]
        [TestCase("FxCopCmd.exe", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_0", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_1", ExpectedException = typeof(ValidationException))]
        [TestCase("fxcop-1.36_2")]
        public void TestValidateFxCopInstallDirecotry(string directory)
        {
            FxCopProcessConfiguration configuration = new FxCopProcessConfiguration();
            configuration.FxCopInstallDirectory = directory;
            FxCopProcessGenerator.ValidateFxCopInstallDirectory(configuration);
        }
    }
}
