from ..service import Operation


class SyncFolderItems(Operation):
    """SyncFolderItems EWS Operation retrieves details about folder items
    """

    RESULTS_KEY = 'Changes'
    FIELD_ACTION_TYPE_MAP = {
        'create': [
            'Item',
            'Message',
            'CalendarItem',
            'Contact',
            'DistributionList',
            'MeetingMessage',
            'MeetingRequest',
            'MeetingResponse',
            'MeetingCancellation',
            'Task'
        ],
        'update': [
            'Item',
            'Message',
            'CalendarItem',
            'Contact',
            'DistributionList',
            'MeetingMessage',
            'MeetingRequest',
            'MeetingResponse',
            'MeetingCancellation',
            'Task'
        ],
        'delete': [
            'ItemId'
        ],
        'readflagchange': [
            'ItemId',
            'IsRead'
        ]
    }
    FIELD_URI_PROPERTIES = [
        "folder:FolderId",
        "folder:ParentFolderId",
        "folder:DisplayName",
        "folder:UnreadCount",
        "folder:TotalCount",
        "folder:ChildFolderCount",
        "folder:FolderClass",
        "folder:SearchParameters",
        "folder:ManagedFolderInformation",
        "folder:PermissionSet",
        "folder:EffectiveRights",
        "folder:SharingEffectiveRights",
        "item:ItemId",
        "item:ParentFolderId",
        "item:ItemClass",
        "item:MimeContent",
        "item:Attachments",
        "item:Subject",
        "item:DateTimeReceived",
        "item:Size",
        "item:Categories",
        "item:HasAttachments",
        "item:Importance",
        "item:InReplyTo",
        "item:InternetMessageHeaders",
        "item:IsAssociated",
        "item:IsDraft",
        "item:IsFromMe",
        "item:IsResend",
        "item:IsSubmitted",
        "item:IsUnmodified",
        "item:DateTimeSent",
        "item:DateTimeCreated",
        "item:Body",
        "item:ResponseObjects",
        "item:Sensitivity",
        "item:ReminderDueBy",
        "item:ReminderIsSet",
        "item:ReminderNextTime",
        "item:ReminderMinutesBeforeStart",
        "item:DisplayTo",
        "item:DisplayCc",
        "item:Culture",
        "item:EffectiveRights",
        "item:LastModifiedName",
        "item:LastModifiedTime",
        "item:ConversationId",
        "item:UniqueBody",
        "item:Flag",
        "item:StoreEntryId",
        "item:InstanceKey",
        "item:NormalizedBody",
        "item:EntityExtractionResult",
        "itemPolicyTag",
        "item:ArchiveTag",
        "item:RetentionDate",
        "item:Preview",
        "item:NextPredictedAction",
        "item:GroupingAction",
        "item:PredictedActionReasons",
        "item:IsClutter",
        "item:RightsManagementLicenseData",
        "item:BlockStatus",
        "item:HasBlockedImages",
        "item:WebClientReadFormQueryString",
        "item:WebClientEditFormQueryString",
        "item:TextBody",
        "item:IconIndex",
        "item:MimeContentUTF8",
        "message:ConversationIndex",
        "message:ConversationTopic",
        "message:InternetMessageId",
        "message:IsRead",
        "message:IsResponseRequested",
        "message:IsReadReceiptRequested",
        "message:IsDeliveryReceiptRequested",
        "message:ReceivedBy",
        "message:ReceivedRepresenting",
        "message:References",
        "message:ReplyTo",
        "message:From",
        "message:Sender",
        "message:ToRecipients",
        "message:CcRecipients",
        "message:BccRecipients",
        "message:ApprovalRequestData",
        "message:VotingInformation",
        "message:ReminderMessageData",
        "meeting:AssociatedCalendarItemId",
        "meeting:IsDelegated",
        "meeting:IsOutOfDate",
        "meeting:HasBeenProcessed",
        "meeting:ResponseType",
        "meeting:ProposedStart",
        "meeting:PropsedEnd",
        "meetingRequest:MeetingRequestType",
        "meetingRequest:IntendedFreeBusyStatus",
        "meetingRequest:ChangeHighlights",
        "calendar:Start",
        "calendar:End",
        "calendar:OriginalStart",
        "calendar:StartWallClock",
        "calendar:EndWallClock",
        "calendar:StartTimeZoneId",
        "calendar:EndTimeZoneId",
        "calendar:IsAllDayEvent",
        "calendar:LegacyFreeBusyStatus",
        "calendar:Location",
        "calendar:When",
        "calendar:IsMeeting",
        "calendar:IsCancelled",
        "calendar:IsRecurring",
        "calendar:MeetingRequestWasSent",
        "calendar:IsResponseRequested",
        "calendar:CalendarItemType",
        "calendar:MyResponseType",
        "calendar:Organizer",
        "calendar:RequiredAttendees",
        "calendar:OptionalAttendees",
        "calendar:Resources",
        "calendar:ConflictingMeetingCount",
        "calendar:AdjacentMeetingCount",
        "calendar:ConflictingMeetings",
        "calendar:AdjacentMeetings",
        "calendar:Duration",
        "calendar:TimeZone",
        "calendar:AppointmentReplyTime",
        "calendar:AppointmentSequenceNumber",
        "calendar:AppointmentState",
        "calendar:Recurrence",
        "calendar:FirstOccurrence",
        "calendar:LastOccurrence",
        "calendar:ModifiedOccurrences",
        "calendar:DeletedOccurrences",
        "calendar:MeetingTimeZone",
        "calendar:ConferenceType",
        "calendar:AllowNewTimeProposal",
        "calendar:IsOnlineMeeting",
        "calendar:MeetingWorkspaceUrl",
        "calendar:NetShowUrl",
        "calendar:UID",
        "calendar:RecurrenceId",
        "calendar:DateTimeStamp",
        "calendar:StartTimeZone",
        "calendar:EndTimeZone",
        "calendar:JoinOnlineMeetingUrl",
        "calendar:OnlineMeetingSettings",
        "calendar:IsOrganizer",
        "task:ActualWork",
        "task:AssignedTime",
        "task:BillingInformation",
        "task:ChangeCount",
        "task:Companies",
        "task:CompleteDate",
        "task:Contacts",
        "task:DelegationState",
        "task:Delegator",
        "task:DueDate",
        "task:IsAssignmentEditable",
        "task:IsComplete",
        "task:IsRecurring",
        "task:IsTeamTask",
        "task:Mileage",
        "task:Owner",
        "task:PercentComplete",
        "task:Recurrence",
        "task:StartDate",
        "task:Status",
        "task:StatusDescription",
        "task:TotalWork",
        "contacts:Alias",
        "contacts:AssistantName",
        "contacts:Birthday",
        "contacts:BusinessHomePage",
        "contacts:Children",
        "contacts:Companies",
        "contacts:CompanyName",
        "contacts:CompleteName",
        "contacts:ContactSource",
        "contacts:Culture",
        "contacts:Department",
        "contacts:DisplayName",
        "contacts:DirectoryId",
        "contacts:DirectReports",
        "contacts:EmailAddresses",
        "contacts:FileAs",
        "contacts:FileAsMapping",
        "contacts:Generation",
        "contacts:GivenName",
        "contacts:ImAddresses",
        "contacts:Initials",
        "contacts:JobTitle",
        "contacts:Manager",
        "contacts:ManagerMailbox",
        "contacts:MiddleName",
        "contacts:Mileage",
        "contacts:MSExchangeCertificate",
        "contacts:Nickname",
        "contacts:Notes",
        "contacts:OfficeLocation",
        "contacts:PhoneNumbers",
        "contacts:PhoneticFullName",
        "contacts:PhoneticFirstName",
        "contacts:PhoneticLastName",
        "contacts:Photo",
        "contacts:PhysicalAddresses",
        "contacts:PostalAddressIndex",
        "contacts:Profession",
        "contacts:SpouseName",
        "contacts:Surname",
        "contacts:WeddingAnniversary",
        "contacts:UserSMIMECertificate",
        "contacts:HasPicture",
        "distributionlist:Members",
        "postitem:PostedTime",
        "conversation:ConversationId",
        "conversation:ConversationTopic",
        "conversation:UniqueRecipients",
        "conversation:GlobalUniqueRecipients",
        "conversation:UniqueUnreadSenders",
        "conversation:GlobalUniqueUnreadSenders",
        "conversation:UniqueSenders",
        "conversation:GlobalUniqueSenders",
        "conversation:LastDeliveryTime",
        "conversation:GlobalLastDeliveryTime",
        "conversation:Categories",
        "conversation:GlobalCategories",
        "conversation:FlagStatus",
        "conversation:GlobalFlagStatus",
        "conversation:HasAttachments",
        "conversation:GlobalHasAttachments",
        "conversation:HasIrm",
        "conversation:GlobalHasIrm",
        "conversation:MessageCount",
        "conversation:GlobalMessageCount",
        "conversation:UnreadCount",
        "conversation:GlobalUnreadCount",
        "conversation:Size",
        "conversation:GlobalSize",
        "conversation:ItemClasses",
        "conversation:GlobalItemClasses",
        "conversation:Importance",
        "conversation:GlobalImportance",
        "conversation:ItemIds",
        "conversation:GlobalItemIds",
        "conversation:LastModifiedTime",
        "conversation:InstanceKey",
        "conversation:Preview",
        "conversation:GlobalParentFolderId",
        "conversation:NextPredictedAction",
        "conversation:GroupingAction",
        "conversation:IconIndex",
        "conversation:GlobalIconIndex",
        "conversation:DraftItemIds",
        "conversation:HasClutter",
        "persona:PersonaId",
        "persona:PersonaType",
        "persona:GivenName",
        "persona:CompanyName",
        "persona:Surname",
        "persona:DisplayName",
        "persona:EmailAddress",
        "persona:FileAs",
        "persona:HomeCity",
        "persona:CreationTime",
        "persona:RelevanceScore",
        "persona:WorkCity",
        "persona:PersonaObjectStatus",
        "persona:FileAsId",
        "persona:DisplayNamePrefix",
        "persona:YomiCompanyName",
        "persona:YomiFirstName",
        "persona:YomiLastName",
        "persona:Title",
        "persona:EmailAddresses",
        "persona:PhoneNumber",
        "persona:ImAddress",
        "persona:ImAddresses",
        "persona:ImAddresses2",
        "persona:ImAddresses3",
        "persona:FolderIds",
        "persona:Attributions",
        "persona:DisplayNames",
        "persona:Initials",
        "persona:FileAses",
        "persona:FileAsIds",
        "persona:DisplayNamePrefixes",
        "persona:GivenNames",
        "persona:MiddleNames",
        "persona:Surnames",
        "persona:Generations",
        "persona:Nicknames",
        "persona:YomiCompanyNames",
        "persona:YomiFirstNames",
        "persona:YomiLastNames",
        "persona:BusinessPhoneNumbers",
        "persona:BusinessPhoneNumbers2",
        "persona:HomePhones",
        "persona:HomePhones2",
        "persona:MobilePhones",
        "persona:MobilePhones2",
        "persona:AssistantPhoneNumbers",
        "persona:CallbackPhones",
        "persona:CarPhones",
        "persona:HomeFaxes",
        "persona:OrganizationMainPhones",
        "persona:OtherFaxes",
        "persona:OtherTelephones",
        "persona:OtherPhones2",
        "persona:Pagers",
        "persona:RadioPhones",
        "persona:TelexNumbers",
        "persona:WorkFaxes",
        "persona:Emails1",
        "persona:Emails2",
        "persona:Emails3",
        "persona:BusinessHomePages",
        "persona:School",
        "persona:PersonalHomePages",
        "persona:OfficeLocations",
        "persona:BusinessAddresses",
        "persona:HomeAddresses",
        "persona:OtherAddresses",
        "persona:Titles",
        "persona:Departments",
        "persona:CompanyNames",
        "persona:Managers",
        "persona:AssistantNames",
        "persona:Professions",
        "persona:SpouseNames",
        "persona:Hobbies",
        "persona:WeddingAnniversaries",
        "persona:Birthdays",
        "persona:Children",
        "persona:Locations",
        "persona:ExtendedProperties",
        "persona:PostalAddress",
        "persona:Bodies"
    ]

    def __init__(self, folder_id, change_key=None):
        """Retrieves details about a provided folder id.

        Args:
            folder_id (str): The folder id to retrieve details about.
            change_key (str, optional): The version key of the folder id. Defaults to None.
        """
        self.folder_id = folder_id
        self.change_key = change_key

    def soap(self):
        if self.change_key:
            folder_id = self.T_NAMESPACE.FolderId(Id=self.folder_id, ChangeKey=self.change_key)
        else:
            folder_id = self.T_NAMESPACE.FolderId(Id=self.folder_id)
        return self.M_NAMESPACE.SyncFolderItems(
            self.M_NAMESPACE.ItemShape(
                self.T_NAMESPACE.BaseShape('AllProperties'),
                self.T_NAMESPACE.IncludeMimeContent('true'),
                self.T_NAMESPACE.BodyType('Best'),
                self.T_NAMESPACE.FilterHtmlContent('false'),
                self.T_NAMESPACE.ConvertHtmlCodePageToUTF8('false')
            ),
            self.M_NAMESPACE.SyncFolderId(
                folder_id
            ),
            self.M_NAMESPACE.MaxChangesReturned('100'),
            self.M_NAMESPACE.SyncScope('NormalAndAssociatedItems')
        )
