/*
 * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 * 
 *  http://aws.amazon.com/apache2.0
 * 
 * or in the "license" file accompanying this file. This file 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.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon.Runtime;
using Amazon.Runtime.SharedInterfaces;
using Amazon.SimpleNotificationService.Model;
using Amazon.Auth.AccessControlPolicy;
using Amazon.Auth.AccessControlPolicy.ActionIdentifiers;
using System.Globalization;
namespace Amazon.SimpleNotificationService
{
    public partial class AmazonSimpleNotificationServiceClient
    {
        /// 
        /// Add statement to the policy that gives the sns topic access to send a message to the queue.
        /// 
        /// 
        /// 
        /// 
        private static void AddSQSPermission(Policy policy, string topicArn, string sqsQueueArn)
        {
            Statement statement = new Statement(Statement.StatementEffect.Allow);
            statement.Actions.Add(SQSActionIdentifiers.SendMessage);
            statement.Resources.Add(new Resource(sqsQueueArn));
            statement.Conditions.Add(ConditionFactory.NewSourceArnCondition(topicArn));
            statement.Principals.Add(new Principal("*"));
            policy.Statements.Add(statement);
        }
        /// 
        /// Check to see if the policy for the queue has already given permission to the topic.
        /// 
        /// 
        /// 
        /// 
        /// 
        private static bool HasSQSPermission(Policy policy, string topicArn, string sqsQueueArn)
        {
            foreach (Statement statement in policy.Statements)
            {
                // See if the statement contains the topic as a resource
                bool containsResource = false;
                foreach (var resource in statement.Resources)
                {
                    if (resource.Id.Equals(sqsQueueArn))
                    {
                        containsResource = true;
                        break;
                    }
                }
                // If queue found as the resource see if the condition is for this topic
                if (containsResource)
                {
                    foreach (var condition in statement.Conditions)
                    {
                        if ((string.Equals(condition.Type, ConditionFactory.StringComparisonType.StringLike.ToString(), StringComparison.OrdinalIgnoreCase) ||
                                string.Equals(condition.Type, ConditionFactory.StringComparisonType.StringEquals.ToString(), StringComparison.OrdinalIgnoreCase) ||
                                string.Equals(condition.Type, ConditionFactory.ArnComparisonType.ArnEquals.ToString(), StringComparison.OrdinalIgnoreCase) ||
                                string.Equals(condition.Type, ConditionFactory.ArnComparisonType.ArnLike.ToString(), StringComparison.OrdinalIgnoreCase)) &&
                            string.Equals(condition.ConditionKey, ConditionFactory.SOURCE_ARN_CONDITION_KEY, StringComparison.OrdinalIgnoreCase) &&
                            condition.Values.Contains(topicArn))
                            return true;
                    }
                }
            }
            return false;
        }
        /// 
        /// Verifies that the ARN for the topic matches the topic name
        /// 
        /// 
        /// 
        /// 
        private static bool TopicNameMatcher(string topicArn, string topicName)
        {
            if (String.IsNullOrEmpty(topicArn))
            {
                return false;
            }
            if (String.IsNullOrEmpty(topicName))
            {
                return false;
            }
            int indexOfLastColon = topicArn.LastIndexOf(":", StringComparison.OrdinalIgnoreCase);
            if (indexOfLastColon.Equals(-1))
            {
                return false;
            }
            return topicArn.Substring(indexOfLastColon + 1).Equals(topicName);
        }
        /// 
        /// Helper method for AuthorizeS3ToPublishAsync()
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private static void GetNewPolicyAndStatementForTopicAttributes(Dictionary attributes, string topicArn, string bucket, out Policy policy, out Statement statement)
        {
            if(attributes.ContainsKey("Policy") && !string.IsNullOrEmpty(attributes["Policy"]))
            {
                policy = Policy.FromJson(attributes["Policy"]);
            }
            else
            {
                policy = new Policy();
            }
            var sourceArn = string.Format(CultureInfo.InvariantCulture, "arn:aws:s3:*:*:{0}", bucket);
            statement = new Statement(Statement.StatementEffect.Allow);
            statement.Actions.Add(SNSActionIdentifiers.Publish);
            statement.Resources.Add(new Resource(topicArn));
            statement.Conditions.Add(ConditionFactory.NewSourceArnCondition(sourceArn));
            statement.Principals.Add(new Principal("*"));
        }
    }
}