/*
 * WvTest:
 *   Copyright (C)2007-2012 Versabanq Innovations Inc. and contributors.
 *       Licensed under the GNU Library General Public License, version 2.
 *       See the included file named LICENSE for license information.
 *       You can get wvtest from: http://github.com/apenwarr/wvtest
 */
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Wv;

// We put this in wvtest.cs since wvtest.cs should be able to compile all
// by itself, without relying on any other parts of wvdotnet.  On the other
// hand, it's perfectly fine for wvdotnet to have wvtest.cs in it.
namespace Wv
{
    public static class WvReflection
    {
	public static IEnumerable<Type> find_types(Type attrtype)
	{
	    foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
	    {
		foreach (Type t in a.GetTypes())
		{
		    if (!t.IsDefined(attrtype, false))
			continue;

		    yield return t;
		}
	    }
	}

	public static IEnumerable<MethodInfo> find_methods(this Type t,
							   Type attrtype)
	{
	    foreach (MethodInfo m in t.GetMethods())
	    {
		if (!m.IsDefined(attrtype, false))
		    continue;

		yield return m;
	    }
	}
    }
}

namespace Wv.Test
{
    public class WvTest
    {
	struct TestInfo
	{
	    public string name;
	    public Action cb;

	    public TestInfo(string name, Action cb)
	        { this.name = name; this.cb = cb; }
	}
        List<TestInfo> tests = new List<TestInfo>();

        public int failures { get; private set; }

	public WvTest()
	{
	    foreach (Type t in
		     WvReflection.find_types(typeof(TestFixtureAttribute)))
	    {
		foreach (MethodInfo m in
			 t.find_methods(typeof(TestAttribute)))
		{
		    // The new t2, m2 are needed so that each delegate gets
		    // its own copy of the variable.
		    Type t2 = t;
		    MethodInfo m2 = m;
		    RegisterTest(String.Format("{0}/{1}",
					       t.Name, m.Name),
				 delegate() {
				     try {
					 m2.Invoke(Activator.CreateInstance(t2),
						   null);
				     } catch (TargetInvocationException e) {
					 throw e.InnerException;
				     }
				 });
		}
	    }
	}

        public void RegisterTest(string name, Action tc)
        {
            tests.Add(new TestInfo(name, tc));
        }

	public static void DoMain()
	{
	    // Enough to run an entire test
	    Environment.Exit(new WvTest().Run());
	}

        public int Run()
        {
	    string[] args = Environment.GetCommandLineArgs();

	    if (args.Length <= 1)
		Console.WriteLine("WvTest: Running all tests");
	    else
		Console.WriteLine("WvTest: Running only selected tests");

            foreach (TestInfo test in tests)
	    {
		string[] parts = test.name.Split(new char[] { '/' }, 2);

		bool runthis = (args.Length <= 1);
		foreach (string arg in args)
		    if (parts[0].StartsWith(arg) || parts[1].StartsWith(arg))
			runthis = true;

		if (!runthis) continue;

                Console.WriteLine("\nTesting \"{0}\" in {1}:",
				  parts[1], parts[0]);

                try {
		    test.cb();
                } catch (WvAssertionFailure) {
                    failures++;
                } catch (Exception e) {
                    Console.WriteLine(e.ToString());
                    Console.WriteLine("! WvTest Exception received   FAILED");
                    failures++;
                }
            }

	    Console.Out.WriteLine("Result: {0} failures.", failures);

	    // Return a safe unix exit code
	    return failures > 0 ? 1 : 0;
        }

	public static bool booleanize(bool x)
	{
	    return x;
	}

	public static bool booleanize(long x)
	{
	    return x != 0;
	}

	public static bool booleanize(ulong x)
	{
	    return x != 0;
	}

	public static bool booleanize(string s)
	{
	    return s != null && s != "";
	}

	public static bool booleanize(object o)
	{
	    return o != null;
	}

	static bool expect_fail = false;
	public static void expect_next_failure()
	{
	    expect_fail = true;
	}

	public static bool test(bool ok, string file, int line, string s)
	{
	    s = s.Replace("\n", "!");
	    s = s.Replace("\r", "!");
	    string suffix = "";
	    if (expect_fail)
	    {
		if (!ok)
		    suffix = " (expected) ok";
		else
		    suffix = " (expected fail!) FAILED";
	    }
	    Console.WriteLine("! {0}:{1,-5} {2,-40} {3}{4}",
			      file, line, s,
			      ok ? "ok" : "FAILED",
			      suffix);
	    Console.Out.Flush();
	    expect_fail = false;

            if (!ok)
	        throw new WvAssertionFailure(String.Format("{0}:{1} {2}", file, line, s));

	    return ok;
	}

	public static void test_exception(string file, int line, string s)
	{
	    Console.WriteLine("! {0}:{1,-5} {2,-40} {3}",
					 file, line, s, "EXCEPTION");
            Console.Out.Flush();
	}

	public static bool test_eq(bool cond1, bool cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 == cond2, file, line,
		String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_eq(long cond1, long cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 == cond2, file, line,
		String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_eq(ulong cond1, ulong cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 == cond2, file, line,
		String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_eq(double cond1, double cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 == cond2, file, line,
		String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_eq(decimal cond1, decimal cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 == cond2, file, line,
		String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_eq(string cond1, string cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 == cond2, file, line,
		String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	// some objects can compare themselves to 'null', which is helpful.
	// for example, DateTime.MinValue == null, but only through
	// IComparable, not through IObject.
	public static bool test_eq(IComparable cond1, IComparable cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1.CompareTo(cond2) == 0, file, line,
			String.Format("[{0}] == [{1}]", s1, s2));
	}

	public static bool test_eq(object cond1, object cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 == cond2, file, line,
		String.Format("[{0}] == [{1}]", s1, s2));
	}

	public static bool test_ne(bool cond1, bool cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 != cond2, file, line,
		String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_ne(long cond1, long cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 != cond2, file, line,
		String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_ne(ulong cond1, ulong cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 != cond2, file, line,
		String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_ne(double cond1, double cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 != cond2, file, line,
		String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_ne(decimal cond1, decimal cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 != cond2, file, line,
		String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	public static bool test_ne(string cond1, string cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 != cond2, file, line,
		String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
			      cond1, cond2, s1, s2));
	}

	// See notes for test_eq(IComparable,IComparable)
	public static bool test_ne(IComparable cond1, IComparable cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1.CompareTo(cond2) != 0, file, line,
			String.Format("[{0}] != [{1}]", s1, s2));
	}

	public static bool test_ne(object cond1, object cond2,
				   string file, int line,
				   string s1, string s2)
	{
	    return test(cond1 != cond2, file, line,
		String.Format("[{0}] != [{1}]", s1, s2));
	}
    }

    public class WvAssertionFailure : Exception
    {
        public WvAssertionFailure()
            : base()
        {
        }

        public WvAssertionFailure(string msg)
            : base(msg)
        {
        }
    }

    // Placeholders for NUnit compatibility
    public class TestFixtureAttribute : Attribute
    {
    }
    public class TestAttribute : Attribute
    {
    }
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
    public class CategoryAttribute : Attribute
    {
        public CategoryAttribute(string x)
        {
        }
    }
}
