using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static String GetBetween(string lin, String find, String find2) {
            int startpos = VbX.InStr(lin, find)+VbX.Len(find)-1;
            if (startpos<0) return "";
            string part2 = VbX.Right(lin, VbX.Len(lin) - startpos);

            int endpos = VbX.InStr(part2, find2) + VbX.Len(find2) - 2;
            if (endpos < 0) return "";

            return part2.Left(endpos);


        
        }

        static void Main(string[] args)
        {
            if (args.Length<3)
            {
                Console.WriteLine("Usage:");
                Console.WriteLine("MakeNeoGeoHash [SourceXML] [DestXML] [RomPath] [CHD info]");
                Console.WriteLine("");
                Console.WriteLine("Looks for lines containing `<rom`");
                Console.WriteLine("Gets filename from `name=\"___\"`");
                Console.WriteLine("Fills in values: %crc% %sha% %size%");
                Console.WriteLine("All lines (after modification) written to DestXML");
                Console.WriteLine("search and replaces are case sensitive!");

#if DEBUG
                Console.ReadLine();
#endif 
                return;
            }
            



            Console.WriteLine("SourceXML:"+ args[0]);
            Console.WriteLine("DestXML :" + args[1]);
            Console.WriteLine("RomPath :" + args[2]);
            
            string cdsha = "";
            
            if (args.Length == 4)
            {
                Console.WriteLine("ChdHash :" + args[3]); 
                System.IO.StreamReader dr2 = new System.IO.StreamReader(args[3]);
                while (!dr2.EndOfStream)
                {

                    string line = dr2.ReadLine();
                    if (VbX.Left(line,5)==("SHA1:")){
                        cdsha=VbX.Right(line,line.Length-5).Trim();
                        Console.WriteLine("ChdHash :" + cdsha);
                    }
                }

            }

            System.IO.StreamReader dr = new System.IO.StreamReader(args[0]);
            System.IO.StreamWriter dw = new System.IO.StreamWriter(args[1]);

            while (!dr.EndOfStream) {

                string line = dr.ReadLine();
                // Console.WriteLine(line);
                if (line.Contains("<rom") || line.Contains("<disk "))
                {
                    string filename = GetBetween(line, "name=\"", "\"");
                    if (line.Contains("<disk")) filename += ".chd";
                    Console.WriteLine("Processing:"+filename);
                    if (filename != "")
                    {
                        string sha = CalculateSHA1(args[2] + "\\" +  filename);
                        string crc = CalculateCRC(args[2]+"\\" + filename);
                        line = line.Replace("%cdsha%", cdsha);
                        line = line.Replace("%sha%", sha);
                        line = line.Replace("%crc%", crc);
                        line = line.Replace("%size%", FileSize(args[2] + "\\" + filename));

                        // Console.WriteLine(line);

                    }
                }
                dw.WriteLine(line);
        }
            dw.Close();

            
#if DEBUG
            Console.ReadLine();
#endif 
        }
        static string CalculateCRC(string filename)
        {
            
            var crc32 = new Crc32();
            var hash = String.Empty;

            using (var fs = System.IO.File.Open(filename, System.IO.FileMode.Open))
                foreach (byte b in crc32.ComputeHash(fs)) hash += b.ToString("x2").ToLower();

            return hash.ToString();
        }
        static string FileSize(string filename)
        {

            return "0x" + VbX.Dec2Hex(new System.IO.FileInfo(filename).Length);
        }
        static string CalculateSHA1(string filename)
        {
            using (var md5 = System.Security.Cryptography.SHA1.Create())
            {
                using (var stream = System.IO.File.OpenRead(filename))
                {
                    var hash = md5.ComputeHash(stream);
                    return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
                }
            }
        }

        static string CalculateMD5(string filename)
        {
            using (var md5 = System.Security.Cryptography.MD5.Create())
            {
                using (var stream = System.IO.File.OpenRead(filename))
                {
                    var hash = md5.ComputeHash(stream);
                    return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
                }
            }
        }
    }
}
