"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimeZoneTransition = void 0;
const ServiceLocalException_1 = require("../../Exceptions/ServiceLocalException");
const ExtensionMethods_1 = require("../../ExtensionMethods");
const Strings_1 = require("../../Strings");
const TimeZonePeriod_1 = require("./TimeZonePeriod");
const TimeZoneTransitionGroup_1 = require("./TimeZoneTransitionGroup");
const TypeContainer_1 = require("../../TypeContainer");
const XmlAttributeNames_1 = require("../../Core/XmlAttributeNames");
const XmlElementNames_1 = require("../../Core/XmlElementNames");
const XmlNamespace_1 = require("../../Enumerations/XmlNamespace");
const ComplexProperty_1 = require("../ComplexProperty");
/**
 * @internal Represents the base class for all time zone transitions.
 */
class TimeZoneTransition extends ComplexProperty_1.ComplexProperty {
    constructor(timeZoneDefinition, targetPeriodOrGroup) {
        super();
        this.timeZoneDefinition = timeZoneDefinition;
        if (targetPeriodOrGroup instanceof TimeZonePeriod_1.TimeZonePeriod) {
            this.targetPeriod = targetPeriodOrGroup;
        }
        else if (targetPeriodOrGroup instanceof TimeZoneTransitionGroup_1.TimeZoneTransitionGroup) {
            this.targetGroup = targetPeriodOrGroup;
        }
    }
    /**
     * @internal Gets the target period of the transition.
     */
    get TargetPeriod() {
        return this.targetPeriod;
    }
    /**
     * @internal Gets the target transition group of the transition.
     */
    get TargetGroup() {
        return this.targetGroup;
    }
    /**
     * @internal Creates a time zone period transition of the appropriate type given an XML element name.
     *
     * @param   {TimeZoneDefinition}    timeZoneDefinition   The time zone definition to which the transition will belong.
     * @param   {string}                xmlElementName       The XML element name.
     * @return  {TimeZoneTransition}    A TimeZonePeriodTransition instance.
     */
    static Create(timeZoneDefinition, xmlElementName) {
        switch (xmlElementName) {
            case XmlElementNames_1.XmlElementNames.AbsoluteDateTransition:
                return new TypeContainer_1.TypeContainer.AbsoluteDateTransition(timeZoneDefinition);
            case XmlElementNames_1.XmlElementNames.RecurringDayTransition:
                return new TypeContainer_1.TypeContainer.RelativeDayOfMonthTransition(timeZoneDefinition);
            case XmlElementNames_1.XmlElementNames.RecurringDateTransition:
                return new TypeContainer_1.TypeContainer.AbsoluteDayOfMonthTransition(timeZoneDefinition);
            case XmlElementNames_1.XmlElementNames.Transition:
                return new TimeZoneTransition(timeZoneDefinition);
            default:
                throw new ServiceLocalException_1.ServiceLocalException(ExtensionMethods_1.StringHelper.Format(Strings_1.Strings.UnknownTimeZonePeriodTransitionType, xmlElementName));
        }
    }
    /**
     * @internal Creates a time zone transition based on the specified transition time.
     *
     * @param   {TimeZoneDefinition}            timeZoneDefinition   The time zone definition that will own the transition.
     * @param   {TimeZonePeriod}                targetPeriod         The period the transition will target.
     * @param   {TimeZoneInfo.TransitionTime}   transitionTime       The transition time to initialize from.
     * @return  {TimeZoneTransition}            A TimeZoneTransition.
     */
    static CreateTimeZoneTransition(timeZoneDefinition, targetPeriod, transitionTime) {
        var transition;
        if (transitionTime.IsFixedDateRule) {
            transition = new TypeContainer_1.TypeContainer.AbsoluteDayOfMonthTransition(timeZoneDefinition, targetPeriod);
        }
        else {
            transition = new TypeContainer_1.TypeContainer.RelativeDayOfMonthTransition(timeZoneDefinition, targetPeriod);
        }
        transition.InitializeFromTransitionTime(transitionTime);
        return transition;
    }
    /**
     * @internal Creates a time zone transition time.
     * @virtual
     *
     * @return  {TimeZoneInfo.TransitionTime}      A TimeZoneInfo.TransitionTime.
     */
    CreateTransitionTime() {
        throw new ServiceLocalException_1.ServiceLocalException(Strings_1.Strings.InvalidOrUnsupportedTimeZoneDefinition);
    }
    /**
     * @internal Gets the name of the XML element.
     *
     * @return  {string}      XML element name.
     */
    GetXmlElementName() {
        return XmlElementNames_1.XmlElementNames.Transition;
    }
    /**
     * @internal Initializes this transition based on the specified transition time.
     * @virtual
     *
     * @param   {TimeZoneInfo.TransitionTime}   transitionTime   The transition time to initialize from.
     */
    InitializeFromTransitionTime(transitionTime) { }
    /**
     * @internal Loads service object from XML.
     *
     * @param   {any}				jsObject	Json Object converted from XML.
     * @param   {ExchangeService}	service	The service.
     */
    LoadFromXmlJsObject(jsObject, service) {
        for (var key in jsObject) {
            switch (key) {
                case XmlElementNames_1.XmlElementNames.To:
                    let targetKind = jsObject[key][XmlAttributeNames_1.XmlAttributeNames.Kind];
                    let targetId = jsObject[key][XmlElementNames_1.XmlElementNames.To];
                    switch (targetKind) {
                        case TimeZoneTransition.PeriodTarget:
                            let targetPeriod = { outValue: null };
                            if (!this.timeZoneDefinition.Periods.tryGetValue(targetId, targetPeriod)) {
                                throw new ServiceLocalException_1.ServiceLocalException(ExtensionMethods_1.StringHelper.Format(Strings_1.Strings.PeriodNotFound, targetId));
                            }
                            else {
                                this.targetPeriod = targetPeriod.outValue;
                            }
                            break;
                        case TimeZoneTransition.GroupTarget:
                            let targetGroup = { outValue: null };
                            if (!this.timeZoneDefinition.TransitionGroups.tryGetValue(targetId, targetGroup)) {
                                throw new ServiceLocalException_1.ServiceLocalException(ExtensionMethods_1.StringHelper.Format(Strings_1.Strings.TransitionGroupNotFound, targetId));
                            }
                            else {
                                this.targetGroup = targetGroup.outValue;
                            }
                            break;
                        default:
                            throw new ServiceLocalException_1.ServiceLocalException(Strings_1.Strings.UnsupportedTimeZonePeriodTransitionTarget);
                    }
                    break;
            }
        }
    }
    /**
     * @internal Writes elements to XML.
     *
     * @param   {EwsServiceXmlWriter}   writer   The writer.
     */
    WriteElementsToXml(writer) {
        writer.WriteStartElement(XmlNamespace_1.XmlNamespace.Types, XmlElementNames_1.XmlElementNames.To);
        if (this.targetPeriod != null) {
            writer.WriteAttributeValue(XmlAttributeNames_1.XmlAttributeNames.Kind, TimeZoneTransition.PeriodTarget);
            writer.WriteValue(this.targetPeriod.Id, XmlElementNames_1.XmlElementNames.To);
        }
        else {
            writer.WriteAttributeValue(XmlAttributeNames_1.XmlAttributeNames.Kind, TimeZoneTransition.GroupTarget);
            writer.WriteValue(this.targetGroup.Id, XmlElementNames_1.XmlElementNames.To);
        }
        writer.WriteEndElement(); // To
    }
    /**
     * @internal Writes to XML.
     *
     * @param   {EwsServiceXmlWriter}   writer   The writer.
     */
    WriteToXml(writer) {
        super.WriteToXml(writer, this.GetXmlElementName());
    }
}
exports.TimeZoneTransition = TimeZoneTransition;
TimeZoneTransition.PeriodTarget = "Period";
TimeZoneTransition.GroupTarget = "Group";
(function (TimeZoneTransition) {
})(TimeZoneTransition = exports.TimeZoneTransition || (exports.TimeZoneTransition = {}));
//# sourceMappingURL=TimeZoneTransition.js.map