using System;
using System.IO;

namespace DirEx
{
    internal class Program
    {
        private static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.Error.WriteLine("Usage DirEx </f|/d> [/day:<num>] [/dir:<path>] [/pattern:<pattern>] /s");
                Console.Error.WriteLine(" /f                 limit result to files");
                Console.Error.WriteLine(" /d                 limit result to directories");
                Console.Error.WriteLine(" /day:<num>         limit to older <num> days");
                Console.Error.WriteLine(" /dir:<path>        path to list, default on working directory");
                Console.Error.WriteLine(" /pattern:<pattern> filter pattern default is *");
                Console.Error.WriteLine(" /s                 search in sub directories");
                Environment.ExitCode = -1;
                Environment.Exit(1);
                return -1;
            }

            var dir = Environment.CurrentDirectory;
            var showFile = false;
            var showDir = false;
            DateTime? day = null;
            var pattern = "*";
            SearchOption option = SearchOption.TopDirectoryOnly;

            foreach (var arg in args)
            {
                var argKv = arg.Split(new[] { ':' }, 2);
                var k = argKv[0].ToLower();
                var v = argKv.Length == 2 ? argKv[1] : null;

                switch (k)
                {
                    default:
                        Console.Error.WriteLine($"Unrecognizable param: {k}");
                        Environment.ExitCode = -1;
                        Environment.Exit(1);
                        return -1;

                    case "/dir":
                        if (string.IsNullOrWhiteSpace(v))
                        {
                            Console.Error.WriteLine("Missing argument in /dir");
                            Environment.ExitCode = -1;
                            Environment.Exit(1);
                            return -1;
                        }

                        dir = v;
                        break;

                    case "/f": showFile = true; break;
                    case "/d": showDir = true; break;
                    case "/pattern":
                        if (string.IsNullOrWhiteSpace(v))
                        {
                            Console.Error.WriteLine("Missing argument in /pattern");
                            Environment.ExitCode = -1;
                            Environment.Exit(1);
                            return -1;
                        }

                        pattern = v;
                        break;

                    case "/day":
                        if (string.IsNullOrWhiteSpace(v))
                        {
                            Console.Error.WriteLine("Missing argument in /day");
                            Environment.ExitCode = -1;
                            Environment.Exit(1);
                            return -1;
                        }

                        if (int.TryParse(v, out var days))
                        {
                            day = DateTime.Now.AddDays(-days);
                        }
                        else
                        {
                            Console.Error.WriteLine("Invalid argument in /day");
                            Environment.ExitCode = -1;
                            Environment.Exit(1);
                            return -1;
                        }
                        break;

                    case "/s":
                        option = SearchOption.AllDirectories;
                        break;
                }
            }

            if (showFile && showDir)
            {
                Console.Error.WriteLine("Conflicted between /f and /d");
                Environment.ExitCode = -1;
                Environment.Exit(1);
                return -1;
            }

            if (!showFile && !showDir)
            {
                Console.Error.WriteLine("Missing /f or /d");
                Environment.ExitCode = -1;
                Environment.Exit(1);
                return -1;
            }

            if (showFile)
            {
                var entries = Directory.GetFiles(dir, pattern, option);
                foreach (var item in entries)
                {
                    if (day.HasValue)
                    {
                        var info = new FileInfo(item);
                        if (info.LastWriteTime < day) Console.WriteLine(item);
                    }
                    else
                    {
                        Console.WriteLine(item);
                    }
                }
            }

            if (showDir)
            {
                var entries = Directory.GetDirectories(dir, pattern, option);
                foreach (var item in entries)
                {
                    if (day.HasValue)
                    {
                        var info = new DirectoryInfo(item);
                        if (info.LastWriteTime < day) Console.WriteLine(item);
                    }
                    else
                    {
                        Console.WriteLine(item);
                    }
                }
            }

            return 0;
        }
    }
}