// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is autogenerated by:
//     mojo/public/tools/bindings/mojom_bindings_generator.py
// For:
//     mojom/vanadium/discovery.mojom
//

package io.v.mojo.discovery;

public final class Advertisement extends org.chromium.mojo.bindings.Struct {

    private static final int STRUCT_SIZE = 48;
    private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(48, 0)};
    private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];

    public static final int ID_LEN = (int) 16L;

    public byte[] id;
    public String interfaceName;
    public String[] addresses;
    public java.util.Map<String, String> attributes;
    public java.util.Map<String, byte[]> attachments;

    private Advertisement(int version) {
        super(STRUCT_SIZE, version);
    }

    public Advertisement() {
        this(0);
    }

    public static Advertisement deserialize(org.chromium.mojo.bindings.Message message) {
        return decode(new org.chromium.mojo.bindings.Decoder(message));
    }

    @SuppressWarnings("unchecked")
    public static Advertisement decode(org.chromium.mojo.bindings.Decoder decoder0) {
        if (decoder0 == null) {
            return null;
        }
        org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
        Advertisement result = new Advertisement(mainDataHeader.elementsOrVersion);
        if (mainDataHeader.elementsOrVersion >= 0) {
            result.id = decoder0.readBytes(8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
        }
        if (mainDataHeader.elementsOrVersion >= 0) {
            result.interfaceName = decoder0.readString(16, false);
        }
        if (mainDataHeader.elementsOrVersion >= 0) {
            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(24, false);
            {
                org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                result.addresses = new String[si1.elementsOrVersion];
                for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
                    result.addresses[i1] = decoder1.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
                }
            }
        }
        if (mainDataHeader.elementsOrVersion >= 0) {
            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(32, true);
            if (decoder1 == null) {
                result.attributes = null;
            } else {
                decoder1.readDataHeaderForMap();
                String[] keys0;
                String[] values0;
                {
                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, false);
                    {
                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                        keys0 = new String[si2.elementsOrVersion];
                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
                            keys0[i2] = decoder2.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, false);
                        }
                    }
                }
                {
                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, false);
                    {
                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(keys0.length);
                        values0 = new String[si2.elementsOrVersion];
                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
                            values0[i2] = decoder2.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, false);
                        }
                    }
                }
                result.attributes = new java.util.HashMap<String, String>();
                for (int index0 = 0; index0 < keys0.length; ++index0) {
                    result.attributes.put(keys0[index0],  values0[index0]);
                }
            }
        }
        if (mainDataHeader.elementsOrVersion >= 0) {
            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(40, true);
            if (decoder1 == null) {
                result.attachments = null;
            } else {
                decoder1.readDataHeaderForMap();
                String[] keys0;
                byte[][] values0;
                {
                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, false);
                    {
                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                        keys0 = new String[si2.elementsOrVersion];
                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
                            keys0[i2] = decoder2.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, false);
                        }
                    }
                }
                {
                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, false);
                    {
                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(keys0.length);
                        values0 = new byte[si2.elementsOrVersion][];
                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
                            values0[i2] = decoder2.readBytes(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                        }
                    }
                }
                result.attachments = new java.util.HashMap<String, byte[]>();
                for (int index0 = 0; index0 < keys0.length; ++index0) {
                    result.attachments.put(keys0[index0],  values0[index0]);
                }
            }
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
        org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
        encoder0.encode(id, 8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
        encoder0.encode(interfaceName, 16, false);
        if (addresses == null) {
            encoder0.encodeNullPointer(24, false);
        } else {
            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(addresses.length, 24, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
            for (int i0 = 0; i0 < addresses.length; ++i0) {
                encoder1.encode(addresses[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
            }
        }
        if (attributes == null) {
            encoder0.encodeNullPointer(32, true);
        } else {
            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encoderForMap(32);
            int size0 = attributes.size();
            String[] keys0 = new String[size0];
            String[] values0 = new String[size0];
            int index0 = 0;
            for (java.util.Map.Entry<String, String> entry0 : attributes.entrySet()) {
                keys0[index0] = entry0.getKey();
                values0[index0] = entry0.getValue();
                ++index0;
            }
            {
                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(keys0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                for (int i1 = 0; i1 < keys0.length; ++i1) {
                    encoder2.encode(keys0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
                }
            }
            {
                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(values0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                for (int i1 = 0; i1 < values0.length; ++i1) {
                    encoder2.encode(values0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
                }
            }
        }
        if (attachments == null) {
            encoder0.encodeNullPointer(40, true);
        } else {
            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encoderForMap(40);
            int size0 = attachments.size();
            String[] keys0 = new String[size0];
            byte[][] values0 = new byte[size0][];
            int index0 = 0;
            for (java.util.Map.Entry<String, byte[]> entry0 : attachments.entrySet()) {
                keys0[index0] = entry0.getKey();
                values0[index0] = entry0.getValue();
                ++index0;
            }
            {
                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(keys0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                for (int i1 = 0; i1 < keys0.length; ++i1) {
                    encoder2.encode(keys0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
                }
            }
            {
                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(values0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                for (int i1 = 0; i1 < values0.length; ++i1) {
                    encoder2.encode(values0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                }
            }
        }
    }

    /**
     * @see Object#equals(Object)
     */
    @Override
    public boolean equals(Object object) {
        if (object == this)
            return true;
        if (object == null)
            return false;
        if (getClass() != object.getClass())
            return false;
        Advertisement other = (Advertisement) object;
        if (!java.util.Arrays.equals(this.id, other.id))
            return false;
        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.interfaceName, other.interfaceName))
            return false;
        if (!java.util.Arrays.deepEquals(this.addresses, other.addresses))
            return false;
        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.attributes, other.attributes))
            return false;
        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.attachments, other.attachments))
            return false;
        return true;
    }

    /**
     * @see Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = prime + getClass().hashCode();
        result = prime * result + java.util.Arrays.hashCode(id);
        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(interfaceName);
        result = prime * result + java.util.Arrays.deepHashCode(addresses);
        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(attributes);
        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(attachments);
        return result;
    }
}

