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

namespace Azyobuzi.Twirunrun
{
    public class MultipartFormDataList : NameObjectCollectionBase
    {
        public void Add(string name, string data)
        {
            BaseAdd(name, data);
        }

        public void Add(string name, BinaryItem item)
        {
            BaseAdd(name, item);
        }

        public void Remove(string name)
        {
            BaseRemove(name);
        }

        public void RemoveAt(int index)
        {
            BaseRemoveAt(index);
        }

        public void WriteToStream(Stream stream, out string boundary)
        {
            boundary = Environment.TickCount.ToString();
            foreach(var _ in this.Keys.Cast<string>().Select(key => new KeyValuePair<string, object>(key, BaseGet(key))))
            {
                if (_.Value is string)
                    stream.WriteAll(string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n", boundary, _.Key, (string)_.Value).ToBytes());
                else if (_.Value is BinaryItem)
                {
                    var item = (BinaryItem)_.Value;
                    stream.WriteAll(string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n", boundary, _.Key, item.Name, item.MimeType).ToBytes());
                    stream.WriteAll(item.Data);
                    stream.WriteAll("\r\n".ToBytes());
                }
            }
            stream.WriteAll(string.Format("--{0}--\r\n", boundary).ToBytes());
        }

        public byte[] ToBytes(out string boundary)
        {
            using (var stream = new MemoryStream())
            {
                WriteToStream(stream, out boundary);
                return stream.ToArray();
            }
        }
    }

    public class BinaryItem
    {
        public string MimeType { set; get; }
        public string Name { set; get; }
        public byte[] Data { set; get; }
    }
}
