using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;

namespace MyWebServices
{
   public enum RestVerbs { GET, PUT, DELETE, POST, UNSUPPORTED };
   public enum OutputFormats { XML, JSON, TEXT };

   public abstract class IRestRequest
   {
      private RestVerbs verb = RestVerbs.UNSUPPORTED;
      private String method = null;
      private String[] arguments = null;
      private String contentType = "xml";
      private String data;
      private NameValueCollection query = null;

      abstract public Boolean IsValid
      {
         get;
      }

      public Int32 StatusCode = 200;

      public RestVerbs Verb
      {
         get { return this.verb; }
      }

      public String Method
      {
         get { return this.method; }
      }

      public String[] Arguments
      {
         get { return this.arguments; }
      }

      public String ContentType
      {
         get
         {
            return (this.contentType == "xml") ? "text/xml" :
               ((this.contentType == "json") ? "application/json" : "text/plain");
         }
      }

      public OutputFormats OutputFormat
      {
         get
         {
            return (this.contentType == "xml") ? OutputFormats.XML :
               ((this.contentType == "json") ? OutputFormats.JSON : OutputFormats.TEXT);
         }
      }

      public String Data
      {
         get { return this.data; }
      }

      public NameValueCollection Query
      {
         get { return this.query; }
      }

      public IRestRequest(System.Web.HttpRequest r)
      {
         String v = r.HttpMethod.ToUpper();
         this.verb = (v == "GET") ? RestVerbs.GET : (
                     (v == "PUT") ? RestVerbs.PUT : (
                     (v == "POST") ? RestVerbs.POST : (
                     (v == "DELETE") ? RestVerbs.DELETE : RestVerbs.UNSUPPORTED)));

         IEnumerable<String> args = (from s in r.Url.Segments select s.Replace("/", "").ToLower()).Skip(1);
         this.method = args.First();
         this.arguments = args.Skip(1).ToArray();

         String f = r.QueryString["format"];
         if ((new[] { "xml", "json", "text" }).Contains(f))
         {
            this.contentType = f;
         }

         if (r.InputStream != null)
         {
            System.IO.Stream s = r.InputStream;
            s.Seek(0, System.IO.SeekOrigin.Begin);
            Int32 len = Convert.ToInt32(s.Length);
            Byte[] arr = new Byte[len];
            s.Read(arr, 0, len);

            if (arr.Length > 0)
            {
               this.data = (new ASCIIEncoding()).GetString(arr);
            }
         }

         this.query = r.QueryString;
      }
   }
}
