﻿/*
 * 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 System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using DotCMIS.CMISWebServicesReference;
using DotCMIS.Enums;
using DotCMIS.Exceptions;

namespace DotCMIS.Binding.AtomPub
{
    internal class AtomWriter
    {
        public static XmlSerializer ObjectSerializer;
        public static XmlSerializer AclSerializer;

        static AtomWriter()
        {
            XmlRootAttribute objectXmlRoot = new XmlRootAttribute("object");
            objectXmlRoot.Namespace = AtomPubConstants.NamespaceRestAtom;
            ObjectSerializer = new XmlSerializer(typeof(cmisObjectType), objectXmlRoot);

            XmlRootAttribute aclXmlRoot = new XmlRootAttribute("acl");
            aclXmlRoot.Namespace = AtomPubConstants.NamespaceCMIS;
            AclSerializer = new XmlSerializer(typeof(cmisAccessControlListType), aclXmlRoot);
        }

        public const string PrefixAtom = "atom";
        public const string PrefixCMIS = "cmis";
        public const string PrefixRestAtom = "cmisra";
        public const string PrefixApacheChemistry = "chemistry";
    }

    internal class AtomEntryWriter
    {
        private const int BufferSize = 64 * 1024;

        private cmisObjectType cmisObject;
        private Stream stream;
        private string mediaType;
        private string filename;

        public AtomEntryWriter(cmisObjectType cmisObject)
            : this(cmisObject, null, null, null)
        {
        }

        public AtomEntryWriter(cmisObjectType cmisObject, string mediaType, string filename, Stream stream)
        {
            if (cmisObject == null || cmisObject.properties == null)
            {
                throw new CmisInvalidArgumentException("Object and properties must not be null!");
            }

            if (stream != null && mediaType == null)
            {
                throw new CmisInvalidArgumentException("Media type must be set if a stream is present!");
            }

            this.cmisObject = cmisObject;
            this.mediaType = mediaType;
            this.filename = filename;
            this.stream = stream;
        }

        public void Write(Stream outStream)
        {
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            xmlWriterSettings.Encoding = new UTF8Encoding(false);

            using (XmlWriter writer = XmlWriter.Create(outStream, xmlWriterSettings))
            {
                // start doc
                writer.WriteStartDocument();

                // start entry
                writer.WriteStartElement(AtomWriter.PrefixAtom, AtomPubConstants.TagEntry, AtomPubConstants.NamespaceAtom);
                writer.WriteAttributeString("xmlns", AtomWriter.PrefixAtom, null, AtomPubConstants.NamespaceAtom);
                writer.WriteAttributeString("xmlns", AtomWriter.PrefixCMIS, null, AtomPubConstants.NamespaceCMIS);
                writer.WriteAttributeString("xmlns", AtomWriter.PrefixRestAtom, null, AtomPubConstants.NamespaceRestAtom);
                if (filename != null)
                {
                    writer.WriteAttributeString("xmlns", AtomWriter.PrefixApacheChemistry, null, AtomPubConstants.NamespaceApacheChemistry);
                }

                // atom:id
                writer.WriteStartElement(AtomWriter.PrefixAtom, AtomPubConstants.TagAtomId, AtomPubConstants.NamespaceAtom);
                writer.WriteString("urn:uuid:00000000-0000-0000-0000-00000000000");
                writer.WriteEndElement();

                // atom:title
                writer.WriteStartElement(AtomWriter.PrefixAtom, AtomPubConstants.TagAtomTitle, AtomPubConstants.NamespaceAtom);
                writer.WriteString(GetTitle());
                writer.WriteEndElement();

                // atom:updated
                writer.WriteStartElement(AtomWriter.PrefixAtom, AtomPubConstants.TagAtomUpdated, AtomPubConstants.NamespaceAtom);
                writer.WriteString(GetUpdated());
                writer.WriteEndElement();

                // content
                if (stream != null)
                {
                    writer.WriteStartElement(AtomWriter.PrefixRestAtom, AtomPubConstants.TagContent, AtomPubConstants.NamespaceRestAtom);

                    writer.WriteStartElement(AtomWriter.PrefixRestAtom, AtomPubConstants.TagContentMediatype, AtomPubConstants.NamespaceRestAtom);
                    writer.WriteString(mediaType);
                    writer.WriteEndElement();

                    if (filename != null)
                    {
                        writer.WriteStartElement(AtomWriter.PrefixApacheChemistry, AtomPubConstants.TagContentFilename, AtomPubConstants.NamespaceApacheChemistry);
                        writer.WriteString(filename);
                        writer.WriteEndElement();
                    }

                    writer.WriteStartElement(AtomWriter.PrefixRestAtom, AtomPubConstants.TagContentBase64, AtomPubConstants.NamespaceRestAtom);
                    WriteContent(writer);
                    writer.WriteEndElement();

                    writer.WriteEndElement();
                }

                // object
                AtomWriter.ObjectSerializer.Serialize(writer, cmisObject);

                // end entry
                writer.WriteEndElement();

                // end document
                writer.WriteEndDocument();

                writer.Flush();
            }
        }

        // ---- internal ----

        private string GetTitle()
        {
            string result = "";

            if (cmisObject.properties != null && cmisObject.properties.Items != null)
            {
                foreach (cmisProperty property in cmisObject.properties.Items)
                {
                    if (PropertyIds.Name == property.propertyDefinitionId && property is cmisPropertyString)
                    {
                        string[] values = ((cmisPropertyString)property).value;
                        if (values != null && values.Length > 0)
                        {
                            return values[0];
                        }
                    }
                }
            }

            return result;
        }

        private string GetUpdated()
        {
            return DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'", CultureInfo.InvariantCulture);
        }

        private void WriteContent(XmlWriter writer)
        {
            using (BinaryReader br = new BinaryReader(stream))
            {
                byte[] buffer = new byte[BufferSize];
                int readBytes = 0;

                do
                {
                    readBytes = br.Read(buffer, 0, BufferSize);
                    writer.WriteBase64(buffer, 0, readBytes);
                } while (BufferSize <= readBytes);
            }
        }
    }

    internal class AtomQueryWriter
    {
        private string statement;
        private bool? searchAllVersions;
        private bool? includeAllowableActions;
        private IncludeRelationshipsFlag? includeRelationships;
        private string renditionFilter;
        private long? maxItems;
        private long? skipCount;

        public AtomQueryWriter(string statement, bool? searchAllVersions,
            bool? includeAllowableActions, IncludeRelationshipsFlag? includeRelationships, string renditionFilter,
            long? maxItems, long? skipCount)
        {
            this.statement = statement;
            this.searchAllVersions = searchAllVersions;
            this.includeAllowableActions = includeAllowableActions;
            this.includeRelationships = includeRelationships;
            this.renditionFilter = renditionFilter;
            this.maxItems = maxItems;
            this.skipCount = skipCount;
        }

        public void Write(Stream outStream)
        {
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            xmlWriterSettings.Encoding = new UTF8Encoding(false);

            using (XmlWriter writer = XmlWriter.Create(outStream, xmlWriterSettings))
            {
                // start doc
                writer.WriteStartDocument();

                // start query
                writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagQuery, AtomPubConstants.NamespaceCMIS);
                writer.WriteAttributeString("xmlns", AtomWriter.PrefixCMIS, null, AtomPubConstants.NamespaceCMIS);

                // cmis:statement
                writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagStatement, AtomPubConstants.NamespaceCMIS);
                writer.WriteString(statement);
                writer.WriteEndElement();

                // cmis:searchAllVersions
                if (searchAllVersions.HasValue)
                {
                    writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagSearchAllVersions, AtomPubConstants.NamespaceCMIS);
                    writer.WriteString(searchAllVersions.Value ? "true" : "false");
                    writer.WriteEndElement();
                }

                // cmis:includeAllowableActions
                if (includeAllowableActions.HasValue)
                {
                    writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagIncludeAllowableActions, AtomPubConstants.NamespaceCMIS);
                    writer.WriteString(includeAllowableActions.Value ? "true" : "false");
                    writer.WriteEndElement();
                }

                // cmis:includeRelationships
                if (includeRelationships.HasValue)
                {
                    writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagIncludeRelationships, AtomPubConstants.NamespaceCMIS);
                    writer.WriteString(includeRelationships.GetCmisValue());
                    writer.WriteEndElement();
                }

                // cmis:renditionFilter
                if (renditionFilter != null)
                {
                    writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagRenditionFilter, AtomPubConstants.NamespaceCMIS);
                    writer.WriteString(renditionFilter);
                    writer.WriteEndElement();
                }

                // cmis:maxItems
                if (maxItems.HasValue)
                {
                    writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagMaxItems, AtomPubConstants.NamespaceCMIS);
                    writer.WriteString(maxItems.ToString());
                    writer.WriteEndElement();
                }

                // cmis:skipCount
                if (skipCount.HasValue)
                {
                    writer.WriteStartElement(AtomWriter.PrefixCMIS, AtomPubConstants.TagSkipCount, AtomPubConstants.NamespaceCMIS);
                    writer.WriteString(skipCount.ToString());
                    writer.WriteEndElement();
                }

                // end query
                writer.WriteEndElement();

                // end document
                writer.WriteEndDocument();

                writer.Flush();
            }
        }
    }
}
