/*
 * 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.Transactions;
using Apache.NMS.ActiveMQ.Transport;
using Apache.NMS.ActiveMQ.Util;

namespace Apache.NMS.ActiveMQ
{
    /// <summary>
    /// Extends the basic Connection class to provide a transacted Connection
    /// instance that operates within the bounds of a .NET Scoped Transaction.
    ///
    /// The default Session creation methods of Connection are overriden here
    /// to always return a TX capable session instance.
    /// </summary>
    public sealed class NetTxConnection : Connection, INetTxConnection
    {
        private NetTxRecoveryPolicy recoveryPolicy = new NetTxRecoveryPolicy();
        private Guid configuredResourceManagerId = Guid.Empty;

        public NetTxConnection(Uri connectionUri, ITransport transport, IdGenerator clientIdGenerator)
            : base(connectionUri, transport, clientIdGenerator)
        {
        }

        public INetTxSession CreateNetTxSession()
        {
            return (INetTxSession) CreateSession(AcknowledgementMode.Transactional);
        }

        public INetTxSession CreateNetTxSession(Transaction tx)
        {
            NetTxSession session = (NetTxSession)CreateSession(AcknowledgementMode.Transactional);
            session.Enlist(tx);
            return session;
        }

        protected override Session CreateActiveMQSession(AcknowledgementMode ackMode)
        {
            CheckConnected();
            return new NetTxSession(this, NextSessionId);
        }

        public NetTxRecoveryPolicy RecoveryPolicy
        {
            get { return this.recoveryPolicy; }
            set { this.recoveryPolicy = value; }
        }

        public Guid ConfiguredResourceManagerId
        {
            get { return this.configuredResourceManagerId; }
            set { this.configuredResourceManagerId = value; }
        }

        internal Guid ResourceManagerGuid
        {
            get
            {
                return ConfiguredResourceManagerId != Guid.Empty ? 
                    ConfiguredResourceManagerId : GuidFromId(ResourceManagerId);
            }
        }

        private static Guid GuidFromId(string id)
        {
            // Remove the ID: prefix, that's non-unique to be sure
            string resId = id.TrimStart("ID:".ToCharArray());

            // Remaing parts should be host-port-timestamp-instance:sequence
            string[] parts = resId.Split(":-".ToCharArray());

            // We don't use the hostname here, just the remaining bits.
            int a = Int32.Parse(parts[parts.Length-4]);
            short b = Int16.Parse(parts[parts.Length-2]);
            short c = Int16.Parse(parts[parts.Length-1]);
            byte[] d = System.BitConverter.GetBytes(Int64.Parse(parts[parts.Length-3]));

            return new Guid(a, b, c, d);
        }
    }
}

