 /*
 * 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.
 */
package org.apache.sis.metadata.iso.citation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.opengis.metadata.citation.Telephone;
import org.apache.sis.metadata.iso.ISOMetadata;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.jaxb.FilterByVersion;
import org.apache.sis.internal.xml.LegacyNamespaces;
import org.apache.sis.internal.jaxb.gco.StringAdapter;
import org.apache.sis.internal.jaxb.code.CI_TelephoneTypeCode;
import org.apache.sis.internal.metadata.Dependencies;

import static org.opengis.annotation.Obligation.OPTIONAL;
import static org.opengis.annotation.Obligation.MANDATORY;
import static org.opengis.annotation.Specification.ISO_19115;

// Branch-specific imports
import org.opengis.util.CodeList;
import org.opengis.annotation.UML;
import org.apache.sis.internal.geoapi.evolution.InterimType;
import org.apache.sis.internal.geoapi.evolution.UnsupportedCodeList;


/**
 * Telephone numbers for contacting the responsible individual or organization.
 * The following property is mandatory in a well-formed metadata according ISO 19115:
 *
 * <div class="preformat">{@code CI_Telephone}
 * {@code   └─number……} Telephone number by which individuals can contact responsible organisation or individual.</div>
 *
 * <div class="section">Differences between versions 2003 and 2014 of ISO 19115</div>
 * For any contact having more than one telephone number, the way to organize the information
 * changed significantly between the two versions of ISO standard:
 *
 * <ul>
 *   <li>In ISO 19115:2003, each {@code Contact} had only one {@code Telephone} instance, but that instance
 *       could have an arbitrary amount of "voice" and "facsimile" numbers. The methods (now deprecated) were
 *       {@link DefaultContact#getPhone()}, {@link #getVoices()} and {@link #getFacsimiles()}.</li>
 *   <li>In ISO 19115:2014, each {@code Contact} has an arbitrary amount of {@code Telephone} instances, and
 *       each telephone has exactly one number. The new methods are {@link DefaultContact#getPhones()},
 *       {@link #getNumber()} and {@link #getNumberType()}.</li>
 * </ul>
 *
 * <div class="section">Limitations</div>
 * <ul>
 *   <li>Instances of this class are not synchronized for multi-threading.
 *       Synchronization, if needed, is caller's responsibility.</li>
 *   <li>Serialized objects of this class are not guaranteed to be compatible with future Apache SIS releases.
 *       Serialization support is appropriate for short term storage or RMI between applications running the
 *       same version of Apache SIS. For long term storage, use {@link org.apache.sis.xml.XML} instead.</li>
 * </ul>
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @author  Cédric Briançon (Geomatys)
 * @author  Rémi Maréchal (Geomatys)
 * @author  Cullen Rombach (Image Matters)
 * @version 1.0
 *
 * @see DefaultContact#getPhones()
 *
 * @since 0.5
 * @module
 */
@XmlType(name = "CI_Telephone_Type", propOrder = {
    "number",           // New in ISO 19115:2014
    "numberType",       // Ibid.
    "voices",           // Legacy ISO 19115:2003
    "facsimiles"        // Ibid.
})
@XmlRootElement(name = "CI_Telephone")
public class DefaultTelephone extends ISOMetadata implements Telephone {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = 5156405432420742237L;

    /**
     * Telephone number by which individuals can contact responsible organization or individual.
     */
    private String number;

    /**
     * Type of telephone number.
     */
    CodeList<?> numberType;

    /**
     * Constructs a default telephone.
     */
    public DefaultTelephone() {
    }

    /**
     * Constructs a telephone with the given number and type.
     *
     * @param number      the telephone number, or {@code null}.
     * @param numberType  the type of telephone number, or {@code null}.
     *
     * @since 0.5
     */
    DefaultTelephone(final String number, final CodeList<?> numberType) {
        this.number     = number;
        this.numberType = numberType;
    }

    /**
     * Constructs a new instance initialized with the values from the specified metadata object.
     * This is a <cite>shallow</cite> copy constructor, since the other metadata contained in the
     * given object are not recursively copied.
     *
     * @param  object  the metadata to copy values from, or {@code null} if none.
     *
     * @see #castOrCopy(Telephone)
     */
    public DefaultTelephone(final Telephone object) {
        super(object);
        if (object != null) {
            if (object instanceof DefaultTelephone) {
                number     = ((DefaultTelephone) object).getNumber();
                numberType = ((DefaultTelephone) object).numberType;
            } else {
                setVoices(object.getVoices());
                setFacsimiles(object.getFacsimiles());
            }
        }
    }

    /**
     * Returns a SIS metadata implementation with the values of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code DefaultTelephone}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code DefaultTelephone} instance is created using the
     *       {@linkplain #DefaultTelephone(Telephone) copy constructor}
     *       and returned. Note that this is a <cite>shallow</cite> copy operation, since the other
     *       metadata contained in the given object are not recursively copied.</li>
     * </ul>
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     */
    public static DefaultTelephone castOrCopy(final Telephone object) {
        if (object == null || object instanceof DefaultTelephone) {
            return (DefaultTelephone) object;
        }
        return new DefaultTelephone(object);
    }

    /**
     * Returns the telephone number by which individuals can contact responsible organization or individual.
     *
     * @return telephone number by which individuals can contact responsible organization or individual.
     *
     * @since 0.5
     */
    @XmlElement(name = "number", required = true)
    @XmlJavaTypeAdapter(StringAdapter.Since2014.class)
    @UML(identifier="number", obligation=MANDATORY, specification=ISO_19115)
    public String getNumber() {
        return number;
    }

    /**
     * Sets the telephone number by which individuals can contact responsible organization or individual.
     *
     * @param  newValue  the new telephone number by which individuals can contact responsible organization or individual.
     *
     * @since 0.5
     */
    public void setNumber(final String newValue) {
        checkWritePermission(number);
        number = newValue;
    }

    /**
     * Returns the type of telephone number, or {@code null} if none.
     * If non-null, the type can be {@code "VOICE"}, {@code "FACSIMILE"} or {@code "SMS"}.
     *
     * <div class="warning"><b>Upcoming API change — specialization</b><br>
     * The return type will be changed to the {@code TelephoneType} code list
     * when GeoAPI will provide it (tentatively in GeoAPI 3.1).
     * </div>
     *
     * @return type of telephone number, or {@code null} if none.
     *
     * @since 0.5
     */
    @InterimType(UnsupportedCodeList.class)
    @XmlElement(name = "numberType")
    @XmlJavaTypeAdapter(CI_TelephoneTypeCode.Since2014.class)
    @UML(identifier="numberType", obligation=OPTIONAL, specification=ISO_19115)
    public CodeList<?> getNumberType() {
        return numberType;
    }

    /**
     * Sets the type of telephone number.
     * If non-null, the type can only be {@code "VOICE"}, {@code "FACSIMILE"} or {@code "SMS"}.
     *
     * <div class="warning"><b>Upcoming API change — specialization</b><br>
     * The argument type will be changed to the {@code TelephoneType} code list when GeoAPI will provide it
     * (tentatively in GeoAPI 3.1). In the meantime, users can define their own code list class as below:
     *
     * {@preformat java
     *   final class UnsupportedCodeList extends CodeList<UnsupportedCodeList> {
     *       private static final List<UnsupportedCodeList> VALUES = new ArrayList<UnsupportedCodeList>();
     *
     *       // Need to declare at least one code list element.
     *       public static final UnsupportedCodeList MY_CODE_LIST = new UnsupportedCodeList("MY_CODE_LIST");
     *
     *       private UnsupportedCodeList(String name) {
     *           super(name, VALUES);
     *       }
     *
     *       public static UnsupportedCodeList valueOf(String code) {
     *           return valueOf(UnsupportedCodeList.class, code);
     *       }
     *
     *       &#64;Override
     *       public UnsupportedCodeList[] family() {
     *           synchronized (VALUES) {
     *               return VALUES.toArray(new UnsupportedCodeList[VALUES.size()]);
     *           }
     *       }
     *   }
     * }
     * </div>
     *
     * @param  newValue  the new type of telephone number.
     *
     * @since 0.5
     */
    public void setNumberType(final CodeList<?> newValue) {
        checkWritePermission(numberType);
        numberType = newValue;
    }

    /**
     * For implementation of {@link #getVoices()} and {@link #getFacsimiles()} deprecated methods.
     * Shall be the telephones list of the enclosing {@link DefaultContact} object.
     *
     * <p>This field references the same collection than {@link DefaultContact#phones} when possible.
     * Note that the link between this collection and {@code DefaultContact.phones} is broken when
     * {@link DefaultContact} is copied by {@link org.apache.sis.metadata.MetadataCopier}, since the
     * {@code Cloner.clone(Object)} method creates a new (unmodifiable) collection.</p>
     *
     * @deprecated This field will be removed after we removed the deprecated public methods.
     */
    @Deprecated
    private Collection<Telephone> owner;

    /**
     * Specifies the collection which contains this telephone number.
     * This method is invoked by {@link DefaultContact#setPhones(Collection)}
     * when the contact "takes possession" of a {@code DefaultTelephone}.
     *
     * <p>This method will be removed after we removed the deprecated public methods.</p>
     *
     * @param  phones  the collection which should contains this telephone number.
     * @return {@code this}, or a copy of this instance if we conservatively choose to not modify this instance.
     */
    final DefaultTelephone setOwner(final Collection<Telephone> phones) {
        if (owner != phones) {
            if (owner != null && !CollectionsExt.identityEquals(owner.iterator(), phones.iterator())) {
                final DefaultTelephone copy = new DefaultTelephone(this);
                copy.owner = phones;
                return copy;
            }
            owner = phones;
        }
        return this;
    }

    /**
     * Returns the collection that own this telephone number, or create a new collection.
     * Creating a new collection is needed when this phone number has not yet been given
     * to a {@link DefaultContact}.
     *
     * <p>This method will be removed after we removed the deprecated public methods.</p>
     */
    final Collection<Telephone> getOwner() {
       if (owner == null) {
           if (super.state() != State.FINAL) {
               owner = new ArrayList<>(4);
               owner.add(this);
           } else {
               owner = Collections.singletonList(this);
           }
       }
       return owner;
    }

    /**
     * Returns the telephone numbers by which individuals can speak to the responsible organization or individual.
     * This method searches in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact that own
     * this phone is known.
     *
     * @return telephone numbers by which individuals can speak to the responsible organization or individual.
     *
     * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #getNumber() number}
     *             with {@code TelephoneType.VOICE}.
     */
    @Override
    @Deprecated
    @Dependencies({"getNumber", "getNumberType"})
    @XmlElement(name = "voice", namespace = LegacyNamespaces.GMD)
    public final Collection<String> getVoices() {
        if (FilterByVersion.LEGACY_METADATA.accept()) {
            return new LegacyTelephones(getOwner(), UnsupportedCodeList.VOICE);
        }
        return null;
    }

    /**
     * Sets the telephone numbers by which individuals can speak to the responsible organization or individual.
     * This method writes in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact that own
     * this phone is known.
     *
     * @param  newValues  the new telephone numbers, or {@code null} if none.
     *
     * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #setNumber(String) number}
     *             code {@code TelephoneType.VOICE}.
     */
    @Deprecated
    public void setVoices(final Collection<? extends String> newValues) {
        ((LegacyTelephones) getVoices()).setValues(newValues);
    }

    /**
     * Returns the telephone numbers of a facsimile machine for the responsible organization or individual.
     * This method searches in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact
     * that own this phone is known.
     *
     * @return telephone numbers of a facsimile machine for the responsible organization or individual.
     *
     * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #getNumber() number}
     *             code {@code TelephoneType.FACSIMILE}.
     */
    @Override
    @Deprecated
    @Dependencies({"getNumber", "getNumberType"})
    @XmlElement(name = "facsimile", namespace = LegacyNamespaces.GMD)
    public final Collection<String> getFacsimiles() {
        if (FilterByVersion.LEGACY_METADATA.accept()) {
            return new LegacyTelephones(getOwner(), UnsupportedCodeList.FACSIMILE);
        }
        return null;                    // Marshalling newer ISO 19115-3 document.
    }

    /**
     * Sets the telephone number of a facsimile machine for the responsible organization or individual.
     * This method writes in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact
     * that own this phone is known.
     *
     * @param  newValues  the new telephone number, or {@code null} if none.
     *
     * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #setNumber(String) number}
     *             with {@code TelephoneType.FACSIMILE}.
     */
    @Deprecated
    public void setFacsimiles(final Collection<? extends String> newValues) {
        ((LegacyTelephones) getFacsimiles()).setValues(newValues);
    }
}
