﻿/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* Kind, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

using PortCMIS.Data;
using PortCMIS.Enums;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
using System.Text;

namespace PortCMIS.Client.Impl
{
    /// <summary>
    /// Operation context implementation.
    /// </summary>
    public class OperationContext : IOperationContext
    {
        /// <summary>
        /// Property selector for all properties ('*').
        /// </summary>
        public const string PropertiesStar = "*";

        /// <summary>
        /// Rendition constant for 'no rendition' ('cmis:none').
        /// </summary>
        public const string RenditionNone = "cmis:none";

        private ISet<string> filter;
        private bool includeAllowableActions;
        private bool includeAcls;
        private IncludeRelationships? includeRelationships;
        private bool includePolicies;
        private ISet<string> renditionFilter;
        private bool includePathSegments;
        private string orderBy;
        private bool cacheEnabled;
        private string cacheKey;
        private int maxItemsPerPage;

        /// <summary>
        /// Constructor with default values.
        /// </summary>
        public OperationContext()
        {
            filter = null;
            includeAcls = false;
            includeAllowableActions = true;
            includePolicies = false;
            includeRelationships = PortCMIS.Enums.IncludeRelationships.None;
            renditionFilter = null;
            includePathSegments = true;
            orderBy = null;
            cacheEnabled = false;
            maxItemsPerPage = 100;

            GenerateCacheKey();
        }

        /// <summary>
        /// Copy constructor.
        /// </summary>
        public OperationContext(IOperationContext source)
        {
            filter = (source.Filter == null ? null : new HashSet<string>(source.Filter));
            includeAcls = source.IncludeAcls;
            includeAllowableActions = source.IncludeAllowableActions;
            includePolicies = source.IncludePolicies;
            includeRelationships = source.IncludeRelationships;
            renditionFilter = (source.RenditionFilter == null ? null : new HashSet<string>(source.RenditionFilter));
            includePathSegments = source.IncludePathSegments;
            orderBy = source.OrderBy;
            cacheEnabled = source.CacheEnabled;
            maxItemsPerPage = source.MaxItemsPerPage;

            GenerateCacheKey();
        }

        /// <summary>
        /// Constructor with given values.
        /// </summary>
        public OperationContext(ISet<string> filter, bool includeAcls, bool includeAllowableActions,
            bool includePolicies, IncludeRelationships includeRelationships, ISet<string> renditionFilter,
            bool includePathSegments, string orderBy, bool cacheEnabled, int maxItemsPerPage)
        {
            this.filter = filter;
            this.includeAcls = includeAcls;
            this.includeAllowableActions = includeAllowableActions;
            this.includePolicies = includePolicies;
            this.includeRelationships = includeRelationships;
            this.renditionFilter = renditionFilter;
            this.includePathSegments = includePathSegments;
            this.orderBy = orderBy;
            this.cacheEnabled = cacheEnabled;
            this.maxItemsPerPage = maxItemsPerPage;

            GenerateCacheKey();
        }

        /// <inheritdoc/>
        public virtual ISet<string> Filter
        {
            get { return filter == null ? null : new HashSet<string>(filter); }
            set
            {
                if (value != null)
                {
                    HashSet<string> tempSet = new HashSet<string>();
                    foreach (string oid in value)
                    {
                        if (oid == null) { continue; }

                        string toid = oid.Trim();
                        if (toid.Length == 0) { continue; }
                        if (toid == PropertiesStar)
                        {
                            tempSet = new HashSet<string>();
                            tempSet.Add(PropertiesStar);
                            break;
                        }
                        if (toid.IndexOf(',') > -1)
                        {
                            throw new ArgumentException("Query ID must not contain a comma!");
                        }

                        tempSet.Add(toid);
                    }

                    if (tempSet.Count == 0) { filter = null; }
                    else { filter = tempSet; }
                }
                else
                {
                    filter = null;
                }

                GenerateCacheKey();
            }
        }

        /// <inheritdoc/>
        public virtual string FilterString
        {
            get
            {
                if (filter == null) { return null; }

                if (filter.Contains(PropertiesStar))
                {
                    return PropertiesStar;
                }

                this.filter.Add(PropertyIds.ObjectId);
                this.filter.Add(PropertyIds.BaseTypeId);
                this.filter.Add(PropertyIds.ObjectTypeId);

                StringBuilder sb = new StringBuilder();

                foreach (String oid in filter)
                {
                    if (sb.Length > 0) { sb.Append(','); }
                    sb.Append(oid);
                }

                return sb.ToString();
            }

            set
            {
                if (value == null || value.Trim().Length == 0)
                {
                    Filter = null;
                    return;
                }

                string[] ids = value.Split(',');
                HashSet<string> tempSet = new HashSet<string>();
                foreach (string qid in ids)
                {
                    tempSet.Add(qid);
                }

                Filter = tempSet;
            }
        }

        /// <inheritdoc/>
        public virtual bool IncludeAllowableActions
        {
            get { return includeAllowableActions; }
            set { includeAllowableActions = value; GenerateCacheKey(); }
        }

        /// <inheritdoc/>
        public virtual bool IncludeAcls
        {
            get { return includeAcls; }
            set { includeAcls = value; GenerateCacheKey(); }
        }

        /// <inheritdoc/>
        public virtual IncludeRelationships? IncludeRelationships
        {
            get { return includeRelationships; }
            set { includeRelationships = value; GenerateCacheKey(); }
        }

        /// <inheritdoc/>
        public virtual bool IncludePolicies
        {
            get { return includePolicies; }
            set { includePolicies = value; GenerateCacheKey(); }
        }

        /// <inheritdoc/>
        public virtual ISet<string> RenditionFilter
        {
            get { return renditionFilter == null ? null : new HashSet<string>(renditionFilter); }
            set
            {
                HashSet<string> tempSet = new HashSet<string>();
                if (value != null)
                {
                    foreach (String rf in value)
                    {
                        if (rf == null) { continue; }

                        String trf = rf.Trim();
                        if (trf.Length == 0) { continue; }
                        if (trf.IndexOf(',') > -1)
                        {
                            throw new ArgumentException("Rendition must not contain a comma!");
                        }

                        tempSet.Add(trf);
                    }

                    if (tempSet.Count == 0)
                    {
                        tempSet.Add(RenditionNone);
                    }
                }
                else
                {
                    tempSet.Add(RenditionNone);
                }

                renditionFilter = tempSet;

                GenerateCacheKey();
            }
        }

        /// <inheritdoc/>
        public virtual string RenditionFilterString
        {
            get
            {
                if (renditionFilter == null) { return null; }

                StringBuilder sb = new StringBuilder();
                foreach (string rf in renditionFilter)
                {
                    if (sb.Length > 0) { sb.Append(','); }
                    sb.Append(rf);
                }

                return sb.ToString();
            }

            set
            {
                if (value == null || value.Trim().Length == 0)
                {
                    RenditionFilter = null;
                    return;
                }

                string[] renditions = value.Split(',');
                HashSet<string> tempSet = new HashSet<string>();
                foreach (string rend in renditions)
                {
                    tempSet.Add(rend);
                }

                RenditionFilter = tempSet;
            }
        }

        /// <inheritdoc/>
        public virtual bool IncludePathSegments
        {
            get { return includePathSegments; }
            set { includePathSegments = value; GenerateCacheKey(); }
        }

        /// <inheritdoc/>
        public virtual string OrderBy
        {
            get { return orderBy; }
            set { orderBy = value; GenerateCacheKey(); }
        }

        /// <inheritdoc/>
        public virtual bool CacheEnabled
        {
            get { return cacheEnabled; }
            set { cacheEnabled = value; GenerateCacheKey(); }
        }

        /// <inheritdoc/>
        public virtual string CacheKey
        {
            get { return cacheKey; }
        }

        /// <inheritdoc/>
        public virtual int MaxItemsPerPage
        {
            get { return maxItemsPerPage; }
            set { maxItemsPerPage = value; }
        }

        /// <summary>
        /// Generates a cache key from the current state of the operation context.
        /// </summary>
        protected virtual void GenerateCacheKey()
        {
            if (!cacheEnabled)
            {
                cacheKey = null;
            }
            else
            {
                StringBuilder sb = new StringBuilder();

                sb.Append(includeAcls ? "1" : "0");
                sb.Append(includeAllowableActions ? "1" : "0");
                sb.Append(includePolicies ? "1" : "0");
                sb.Append("|");
                sb.Append(filter == null ? "" : FilterString);
                sb.Append("|");
                sb.Append(includeRelationships == null ? "" : includeRelationships.GetCmisValue());
                sb.Append("|");
                sb.Append(renditionFilter == null ? "" : RenditionFilterString);

                cacheKey = sb.ToString();
            }
        }
    }

    /// <summary>
    /// Operation Context helpers.
    /// </summary>
    public class OperationContextUtils
    {
        private OperationContextUtils()
        {
        }

        /// <summary>
        /// Creates a new operation context object.
        /// </summary>
        public static IOperationContext CreateOperationContext()
        {
            return new OperationContext();
        }

        /// <summary>
        /// Copies an operation context object.
        /// </summary>
        public static IOperationContext CopyOperationContext(OperationContext context)
        {
            return new OperationContext(context);
        }

        /// <summary>
        /// Creates a new operation context object with the given parameters.
        /// </summary>
        /// <remarks>
        /// Caching is enabled.
        /// </remarks>
        public static IOperationContext CreateOperationContext(HashSet<string> filter, bool includeAcls,
                bool includeAllowableActions, bool includePolicies, IncludeRelationships includeRelationships,
                HashSet<string> renditionFilter, bool includePathSegments, string orderBy, bool cacheEnabled,
                int maxItemsPerPage)
        {
            return new OperationContext(filter, includeAcls, includeAllowableActions, includePolicies,
                    includeRelationships, renditionFilter, includePathSegments, orderBy, cacheEnabled, maxItemsPerPage);
        }

        /// <summary>
        /// Creates a new operation context object that only selects the bare minimum.
        /// </summary>
        /// <remarks>
        /// Caching is enabled.
        /// </remarks>
        public static IOperationContext CreateMinimumOperationContext()
        {
            return CreateMinimumOperationContext((string[])null);
        }

        /// <summary>
        /// Creates a new operation context object that only selects the bare minimum plus the provided properties.
        /// </summary>
        /// <remarks>
        /// Caching is enabled.
        /// </remarks>
        public static IOperationContext CreateMinimumOperationContext(params string[] property)
        {
            ISet<string> filter = new HashSet<string>();
            filter.Add(PropertyIds.ObjectId);
            filter.Add(PropertyIds.ObjectTypeId);
            filter.Add(PropertyIds.BaseTypeId);

            if (property != null)
            {
                foreach (string prop in property)
                {
                    filter.Add(prop);
                }
            }

            return new OperationContext(filter, false, false, false, IncludeRelationships.None,
                new HashSet<string>() { OperationContext.RenditionNone }, false, null, true, 100);
        }

        /// <summary>
        /// Creates a new operation context object that selects everything.
        /// </summary>
        /// <remarks>
        /// Caching is enabled.
        /// </remarks>
        public static IOperationContext CreateMaximumOperationContext()
        {
            return new OperationContext(new HashSet<string>() { OperationContext.PropertiesStar }, true,
                true, true, IncludeRelationships.Both, new HashSet<string>() { "*" }, false, null, true, 100);
        }

        /// <summary>
        /// Returns an unmodifiable view of the specified operation context.
        /// </summary>
        public static IOperationContext CreateReadOnlyOperationContext(IOperationContext context)
        {
            return new ReadOnlyOperationContext(context);
        }

        internal class ReadOnlyOperationContext : OperationContext
        {
            public ReadOnlyOperationContext(IOperationContext originalContext) : base(originalContext) { }

            public override ISet<string> Filter
            {
                get { return base.Filter == null ? null : new HashSet<string>(base.Filter); }
                set { throw new Exception("Not supported!"); }
            }

            public override string FilterString
            {
                get { return base.FilterString; }
                set { throw new Exception("Not supported!"); }
            }

            public override bool IncludeAllowableActions
            {
                get { return base.IncludeAllowableActions; }
                set { throw new Exception("Not supported!"); }
            }

            public override bool IncludeAcls
            {
                get { return base.IncludeAcls; }
                set { throw new Exception("Not supported!"); }
            }

            public override IncludeRelationships? IncludeRelationships
            {
                get { return base.IncludeRelationships; }
                set { throw new Exception("Not supported!"); }
            }

            public override bool IncludePolicies
            {
                get { return base.IncludePolicies; }
                set { throw new Exception("Not supported!"); }
            }

            public override ISet<string> RenditionFilter
            {
                get { return base.RenditionFilter == null ? null : new HashSet<string>(base.RenditionFilter); }
                set { throw new Exception("Not supported!"); }
            }

            public override string RenditionFilterString
            {
                get { return base.RenditionFilterString; }
                set { throw new Exception("Not supported!"); }
            }

            public override bool IncludePathSegments
            {
                get { return base.IncludePathSegments; }
                set { throw new Exception("Not supported!"); }
            }

            public override string OrderBy
            {
                get { return base.OrderBy; }
                set { throw new Exception("Not supported!"); }
            }

            public override bool CacheEnabled
            {
                get { return base.CacheEnabled; }
                set { throw new Exception("Not supported!"); }
            }

            public override int MaxItemsPerPage
            {
                get { return base.MaxItemsPerPage; }
                set { throw new Exception("Not supported!"); }
            }
        }
    }


    /// <summary>
    /// Object ID implementation.
    /// </summary>
    public class ObjectId : IObjectId
    {
        private string id;

        /// <inheritdoc/>
        public string Id
        {
            get { return id; }
            set
            {
                if (value == null || value.Length == 0)
                {
                    throw new ArgumentException("ID must be set!");
                }

                id = value;
            }
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="id">the object ID as a string</param>
        public ObjectId(string id)
        {
            Id = id;
        }
    }

    /// <summary>
    /// Tree implementation.
    /// </summary>
    public class Tree<T> : ITree<T>
    {
        /// <inheritdoc/>
        public T Item { get; set; }

        /// <inheritdoc/>
        public IList<ITree<T>> Children { get; set; }
    }

    /// <summary>
    /// Base class for IItemEnumerable's.
    /// </summary>
    public abstract class AbstractEnumerable<T> : IItemEnumerable<T>
    {
        private AbstractEnumerator<T> enumerator;
        protected AbstractEnumerator<T> Enumerator
        {
            get
            {
                if (enumerator == null) { enumerator = CreateEnumerator(); }
                return enumerator;
            }
        }

        protected PageFetcher<T> PageFetcher { get; set; }
        protected BigInteger SkipCount { get; private set; }

        public AbstractEnumerable(PageFetcher<T> pageFetcher) :
            this(0, pageFetcher) { }

        protected AbstractEnumerable(BigInteger position, PageFetcher<T> pageFetcher)
        {
            this.PageFetcher = pageFetcher;
            this.SkipCount = position;
        }

        protected abstract AbstractEnumerator<T> CreateEnumerator();

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public IEnumerator<T> GetEnumerator()
        {
            return Enumerator;
        }

        public IItemEnumerable<T> SkipTo(BigInteger position)
        {
            return new CollectionEnumerable<T>(position, PageFetcher);
        }

        public IItemEnumerable<T> GetPage()
        {
            return new CollectionPageEnumerable<T>(SkipCount, PageFetcher);
        }

        public IItemEnumerable<T> GetPage(int maxNumItems)
        {
            PageFetcher.MaxNumItems = maxNumItems;
            return new CollectionPageEnumerable<T>(SkipCount, PageFetcher);
        }

        public BigInteger PageNumItems { get { return Enumerator.PageNumItems; } }

        public bool HasMoreItems { get { return Enumerator.HasMoreItems; } }

        public BigInteger TotalNumItems { get { return Enumerator.TotalNumItems; } }
    }

    /// <summary>
    /// Abstract Enumerator implementation.
    /// </summary>
    public abstract class AbstractEnumerator<T> : IEnumerator<T>
    {
        private PageFetcher<T> pageFetcher;
        private PageFetcher<T>.Page<T> page = null;
        private BigInteger? totalNumItems = null;
        private bool? hasMoreItems = null;

        protected T current;

        public AbstractEnumerator(BigInteger skipCount, PageFetcher<T> pageFetcher)
        {
            this.SkipCount = skipCount;
            this.pageFetcher = pageFetcher;
        }

        /// <inheritdoc/>
        T IEnumerator<T>.Current { get { return Current; } }

        /// <inheritdoc/>
        object IEnumerator.Current { get { return Current; } }

        /// <inheritdoc/>
        public T Current { get { return current; } }

        /// <summary>
        /// Reset is not supported.
        /// </summary>
        public void Reset()
        {
            throw new NotSupportedException();
        }

        /// <inheritdoc/>
        public abstract bool MoveNext();

        /// <inheritdoc/>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <inheritdoc/>
        protected virtual void Dispose(bool disposing)
        {
        }

        public BigInteger SkipCount { get; protected set; }

        public int SkipOffset { get; protected set; }

        public BigInteger Position { get { return SkipCount + SkipOffset; } }

        public BigInteger PageNumItems
        {
            get
            {
                PageFetcher<T>.Page<T> page = GetCurrentPage();
                if (page != null)
                {
                    IList<T> items = page.Items;
                    if (items != null)
                    {
                        return items.Count;
                    }
                }
                return 0;
            }
        }

        public BigInteger TotalNumItems
        {
            get
            {
                if (totalNumItems == null)
                {
                    totalNumItems = -1;
                    PageFetcher<T>.Page<T> page = GetCurrentPage();
                    if (page != null)
                    {
                        totalNumItems = page.TotalNumItems;
                    }
                }
                return (BigInteger)totalNumItems;
            }
        }

        public bool HasMoreItems
        {
            get
            {
                if (hasMoreItems == null)
                {
                    hasMoreItems = false;
                    PageFetcher<T>.Page<T> page = GetCurrentPage();
                    if (page != null)
                    {
                        if (page.HasMoreItems.HasValue)
                        {
                            hasMoreItems = page.HasMoreItems;
                        }
                    }
                }
                return (bool)hasMoreItems;
            }
        }

        protected int IncrementSkipOffset()
        {
            return SkipOffset++;
        }

        protected PageFetcher<T>.Page<T> GetCurrentPage()
        {
            if (page == null)
            {
                page = pageFetcher.FetchNextPage(SkipCount);
            }
            return page;
        }

        protected PageFetcher<T>.Page<T> IncrementPage()
        {
            SkipCount += SkipOffset;
            SkipOffset = 0;
            totalNumItems = null;
            hasMoreItems = null;
            page = pageFetcher.FetchNextPage(SkipCount);
            return page;
        }
    }

    /// <summary>
    /// Page fetcher.
    /// </summary>
    public class PageFetcher<T>
    {
        public delegate Page<T> FetchPage(BigInteger maxNumItems, BigInteger skipCount);

        private FetchPage fetchPageDelegate;

        public PageFetcher(BigInteger maxNumItems, FetchPage fetchPageDelegate)
        {
            MaxNumItems = maxNumItems;
            this.fetchPageDelegate = fetchPageDelegate;
        }

        public BigInteger MaxNumItems { get; set; }

        public Page<T> FetchNextPage(BigInteger skipCount)
        {
            return fetchPageDelegate(MaxNumItems, skipCount);
        }

        public class Page<P>
        {
            public Page(IList<P> items, BigInteger? totalNumItems, bool? hasMoreItems)
            {
                Items = items;
                TotalNumItems = totalNumItems;
                HasMoreItems = hasMoreItems;
            }

            public IList<P> Items { get; private set; }
            public BigInteger? TotalNumItems { get; private set; }
            public bool? HasMoreItems { get; private set; }
        }
    }

    /// <summary>
    /// CMIS Collection Enumerable.
    /// </summary>
    public class CollectionEnumerable<T> : AbstractEnumerable<T>
    {
        public CollectionEnumerable(PageFetcher<T> pageFetcher) :
            this(0, pageFetcher) { }

        public CollectionEnumerable(BigInteger position, PageFetcher<T> pageFetcher) :
            base(position, pageFetcher) { }

        protected override AbstractEnumerator<T> CreateEnumerator()
        {
            return new CollectionEnumerator<T>(SkipCount, PageFetcher);
        }
    }

    /// <summary>
    /// Enumerator for iterating over all items in a CMIS Collection.
    /// </summary>
    public class CollectionEnumerator<T> : AbstractEnumerator<T>
    {
        public CollectionEnumerator(BigInteger skipCount, PageFetcher<T> pageFetcher) :
            base(skipCount, pageFetcher) { }

        public override bool MoveNext()
        {
            PageFetcher<T>.Page<T> page = GetCurrentPage();
            if (page == null)
            {
                return false;
            }

            IList<T> items = page.Items;
            if (items == null || items.Count == 0)
            {
                return false;
            }

            if (SkipOffset == items.Count)
            {
                if (!HasMoreItems)
                {
                    return false;
                }

                page = IncrementPage();
                items = page == null ? null : page.Items;
            }

            if (items == null || items.Count == 0 || SkipOffset == items.Count)
            {
                return false;
            }

            current = items[IncrementSkipOffset()];

            return true;
        }
    }

    /// <summary>
    /// Enumerable for a CMIS Collection Page.
    /// </summary>
    public class CollectionPageEnumerable<T> : AbstractEnumerable<T>
    {
        public CollectionPageEnumerable(PageFetcher<T> pageFetcher) :
            this(0, pageFetcher) { }

        public CollectionPageEnumerable(BigInteger position, PageFetcher<T> pageFetcher) :
            base(position, pageFetcher) { }

        protected override AbstractEnumerator<T> CreateEnumerator()
        {
            return new CollectionPageEnumerator<T>(SkipCount, PageFetcher);
        }
    }

    /// <summary>
    /// Enumerator for iterating over a page of items in a CMIS Collection.
    /// </summary>
    public class CollectionPageEnumerator<T> : AbstractEnumerator<T>
    {
        public CollectionPageEnumerator(BigInteger skipCount, PageFetcher<T> pageFetcher) :
            base(skipCount, pageFetcher) { }

        public override bool MoveNext()
        {
            PageFetcher<T>.Page<T> page = GetCurrentPage();
            if (page == null)
            {
                return false;
            }

            IList<T> items = page.Items;
            if (items == null || items.Count == 0 || SkipOffset == items.Count)
            {
                return false;
            }

            current = items[IncrementSkipOffset()];

            return true;
        }
    }

    /// <summary>
    /// Content Stream helpers.
    /// </summary>
    public class ContentStreamUtils
    {
        /// <summary>Octet Stream MIME type.</summary>
        private const string OctetStream = "application/octet-stream";

        private ContentStreamUtils()
        {
        }

        /// <summary>
        /// Creates a content stream object.
        /// </summary>
        /// <param name="filename">the filename</param>
        /// <param name="length">the length</param>
        /// <param name="mimetype">the MIME type</param>
        /// <param name="stream">the stream</param>
        /// <returns>the content stream</returns>
        public static IContentStream CreateContentStream(string filename, BigInteger? length, string mimetype, Stream stream)
        {
            return new ContentStream()
            {
                FileName = CheckFilename(filename),
                Length = length,
                MimeType = CheckMimeType(mimetype),
                Stream = stream
            };
        }

        // --- byte arrays ---

        /// <summary>
        /// Creates a content stream object from a byte array.
        /// </summary>
        /// <param name="filename">the filename</param>
        /// <param name="contentBytes">the byte array</param>
        /// <param name="mimetype">the MIME type</param>
        /// <returns>the content stream</returns>
        public static IContentStream CreateByteArrayContentStream(string filename, byte[] contentBytes, string mimetype)
        {
            if (contentBytes == null)
            {
                return CreateContentStream(filename, null, mimetype, null);
            }

            return CreateByteArrayContentStream(filename, contentBytes, 0, contentBytes.Length, mimetype);
        }

        /// <summary>
        /// Creates a content stream object from a byte array.
        /// </summary>
        /// <param name="filename">the filename</param>
        /// <param name="contentBytes">the byte array</param>
        /// <param name="index">the begin of the stream in the byte array</param>
        /// <param name="count">the length of the stream</param>
        /// <param name="mimetype">the MIME type</param>
        /// <returns>the content stream</returns>
        public static IContentStream CreateByteArrayContentStream(string filename, byte[] contentBytes, int index, int count, string mimetype)
        {
            if (contentBytes == null)
            {
                return CreateContentStream(filename, null, mimetype, null);
            }

            if (index < 0 || index > contentBytes.Length)
            {
                throw new ArgumentOutOfRangeException("index");
            }
            else if (count < 0 || (index + count) > contentBytes.Length || (index + count) < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            return CreateContentStream(filename, count, mimetype, new MemoryStream(contentBytes, index, count));
        }

        // --- strings ---

        /// <summary>
        /// Creates a content stream object from a string.
        /// </summary>
        /// <param name="filename">the filename</param>
        /// <param name="content">the content</param>
        /// <returns>the content stream</returns>
        public static IContentStream CreateTextContentStream(string filename, string content)
        {
            return CreateTextContentStream(filename, content, "text/plain; charset=UTF-8");
        }

        /// <summary>
        /// Creates a content stream object from a string.
        /// </summary>
        /// <param name="filename">the filename</param>
        /// <param name="content">the content</param>
        /// <param name="mimetype">the MIME type</param>
        /// <returns>the content stream</returns>
        public static IContentStream CreateTextContentStream(string filename, string content, string mimetype)
        {
            byte[] contentBytes = Encoding.UTF8.GetBytes(content);
            return CreateByteArrayContentStream(filename, contentBytes, CheckMimeType(mimetype));
        }

        // ---

        private static string CheckFilename(string filename)
        {
            if (filename == null || filename.Length == 0)
            {
                return "content";
            }

            return filename;
        }

        private static string CheckMimeType(string mimetype)
        {
            if (mimetype == null)
            {
                return OctetStream;
            }

            string result = mimetype.Trim();
            if (result.Length < 3)
            {
                return OctetStream;
            }

            return result;
        }
    }

    internal class StringListBuilder
    {
        private string seperator;
        private bool first;
        public StringBuilder StringBuilder { get; private set; }

        public StringListBuilder() : this(",", new StringBuilder()) { }

        public StringListBuilder(StringBuilder stringBuilder) : this(",", stringBuilder) { }

        public StringListBuilder(string seperator) : this(seperator, new StringBuilder()) { }

        public StringListBuilder(string seperator, StringBuilder stringBuilder)
        {
            this.seperator = seperator;
            StringBuilder = stringBuilder;
            first = true;
        }

        public void Add(string s)
        {
            if (!first)
            {
                StringBuilder.Append(seperator);
            }
            else
            {
                first = false;
            }

            StringBuilder.Append(s);
        }

        override public string ToString()
        {
            return StringBuilder.ToString();
        }
    }
}
