/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed 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 android.view;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;

/** Display identifier that is stable across reboots.
 *
 * @hide
 */
public abstract class DisplayAddress implements Parcelable {
    /**
     * Creates an address for a physical display given its stable ID.
     *
     * A physical display ID is stable if the display can be identified using EDID information.
     *
     * @param physicalDisplayId A physical display ID.
     * @return The {@link Physical} address.
     * @see SurfaceControl#getPhysicalDisplayIds
     */
    @NonNull
    public static Physical fromPhysicalDisplayId(long physicalDisplayId) {
        return new Physical(physicalDisplayId);
    }

    /**
     * Creates an address for a physical display given its port and model.
     *
     * @param port A port in the range [0, 255] interpreted as signed.
     * @param model A positive integer, or {@code null} if the model cannot be identified.
     * @return The {@link Physical} address.
     */
    @NonNull
    public static Physical fromPortAndModel(byte port, Long model) {
        return new Physical(port, model);
    }

    /**
     * Creates an address for a network display given its MAC address.
     *
     * @param macAddress A MAC address in colon notation.
     * @return The {@link Network} address.
     */
    @NonNull
    public static Network fromMacAddress(String macAddress) {
        return new Network(macAddress);
    }

    /**
     * Address for a physically connected display.
     *
     * A {@link Physical} address is represented by a 64-bit identifier combining the port and model
     * of a display. The port, located in the least significant byte, uniquely identifies a physical
     * connector on the device for display output like eDP or HDMI. The model, located in the upper
     * bits, uniquely identifies a display model across manufacturers by encoding EDID information.
     * While the port is always stable, the model may not be available if EDID identification is not
     * supported by the platform, in which case the address is not unique.
     */
    public static final class Physical extends DisplayAddress {
        private static final long UNKNOWN_MODEL = 0;
        private static final int MODEL_SHIFT = 8;

        private final long mPhysicalDisplayId;

        /**
         * Stable display ID combining port and model.
         *
         * @return An ID in the range [0, 2^64) interpreted as signed.
         * @see SurfaceControl#getPhysicalDisplayIds
         */
        public long getPhysicalDisplayId() {
            return mPhysicalDisplayId;
        }

        /**
         * Physical port to which the display is connected.
         *
         * @return A port in the range [0, 255] interpreted as signed.
         */
        public byte getPort() {
            return (byte) mPhysicalDisplayId;
        }

        /**
         * Model identifier unique across manufacturers.
         *
         * @return A positive integer, or {@code null} if the model cannot be identified.
         */
        @Nullable
        public Long getModel() {
            final long model = mPhysicalDisplayId >>> MODEL_SHIFT;
            return model == UNKNOWN_MODEL ? null : model;
        }

        @Override
        public boolean equals(Object other) {
            return other instanceof Physical
                    && mPhysicalDisplayId == ((Physical) other).mPhysicalDisplayId;
        }

        @Override
        public String toString() {
            final StringBuilder builder = new StringBuilder("{")
                    .append("port=").append(Byte.toUnsignedInt(getPort()));

            final Long model = getModel();
            if (model != null) {
                builder.append(", model=0x").append(Long.toHexString(model));
            }

            return builder.append("}").toString();
        }

        @Override
        public int hashCode() {
            return Long.hashCode(mPhysicalDisplayId);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeLong(mPhysicalDisplayId);
        }

        private Physical(long physicalDisplayId) {
            mPhysicalDisplayId = physicalDisplayId;
        }

        private Physical(byte port, Long model) {
            mPhysicalDisplayId = Byte.toUnsignedLong(port)
                    | (model == null ? UNKNOWN_MODEL : (model << MODEL_SHIFT));
        }

        public static final @NonNull Parcelable.Creator<Physical> CREATOR =
                new Parcelable.Creator<Physical>() {
                    @Override
                    public Physical createFromParcel(Parcel in) {
                        return new Physical(in.readLong());
                    }

                    @Override
                    public Physical[] newArray(int size) {
                        return new Physical[size];
                    }
                };
    }

    /**
     * Address for a network-connected display.
     */
    public static final class Network extends DisplayAddress {
        private final String mMacAddress;

        @Override
        public boolean equals(Object other) {
            return other instanceof Network && mMacAddress.equals(((Network) other).mMacAddress);
        }

        @Override
        public String toString() {
            return mMacAddress;
        }

        @Override
        public int hashCode() {
            return mMacAddress.hashCode();
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeString(mMacAddress);
        }

        private Network(String macAddress) {
            mMacAddress = macAddress;
        }

        public static final @NonNull Parcelable.Creator<Network> CREATOR =
                new Parcelable.Creator<Network>() {
                    @Override
                    public Network createFromParcel(Parcel in) {
                        return new Network(in.readString());
                    }

                    @Override
                    public Network[] newArray(int size) {
                        return new Network[size];
                    }
                };
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
