/*
 * Copyright (C) 2016 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 com.android.server.connectivity;

import android.net.ConnectivityMetricsEvent;
import android.net.metrics.ApfProgramEvent;
import android.net.metrics.ApfStats;
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.DhcpClientEvent;
import android.net.metrics.DhcpErrorEvent;
import android.net.metrics.DnsEvent;
import android.net.metrics.IpManagerEvent;
import android.net.metrics.IpReachabilityEvent;
import android.net.metrics.NetworkEvent;
import android.net.metrics.RaEvent;
import android.net.metrics.ValidationProbeEvent;
import com.google.protobuf.nano.MessageNano;
import java.util.Arrays;
import junit.framework.TestCase;

import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
import static com.android.server.connectivity.MetricsTestUtil.aBool;
import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
import static com.android.server.connectivity.MetricsTestUtil.aLong;
import static com.android.server.connectivity.MetricsTestUtil.aString;
import static com.android.server.connectivity.MetricsTestUtil.aType;
import static com.android.server.connectivity.MetricsTestUtil.anInt;
import static com.android.server.connectivity.MetricsTestUtil.anIntArray;
import static com.android.server.connectivity.MetricsTestUtil.b;
import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent;
import static com.android.server.connectivity.MetricsTestUtil.ipEv;

public class IpConnectivityEventBuilderTest extends TestCase {

    public void testDefaultNetworkEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(DefaultNetworkEvent.class),
                anInt(102),
                anIntArray(1, 2, 3),
                anInt(101),
                aBool(true),
                aBool(false));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  default_network_event <",
                "    network_id <",
                "      network_id: 102",
                "    >",
                "    previous_network_id <",
                "      network_id: 101",
                "    >",
                "    previous_network_ip_support: 1",
                "    transport_types: 1",
                "    transport_types: 2",
                "    transport_types: 3",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testDhcpClientEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(DhcpClientEvent.class),
                aString("wlan0"),
                aString("SomeState"),
                anInt(192));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  dhcp_event <",
                "    duration_ms: 192",
                "    error_code: 0",
                "    if_name: \"wlan0\"",
                "    state_transition: \"SomeState\"",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testDhcpErrorEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(DhcpErrorEvent.class),
                aString("wlan0"),
                anInt(DhcpErrorEvent.L4_NOT_UDP));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  dhcp_event <",
                "    duration_ms: 0",
                "    error_code: 50397184",
                "    if_name: \"wlan0\"",
                "    state_transition: \"\"",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testDnsEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(DnsEvent.class),
                anInt(101),
                aByteArray(b(1), b(1), b(2), b(1), b(1), b(1), b(2), b(2)),
                aByteArray(b(0), b(0), b(22), b(3), b(1), b(0), b(200), b(178)),
                anIntArray(3456, 267, 1230, 45, 2111, 450, 638, 1300));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  dns_lookup_batch <",
                "    event_types: 1",
                "    event_types: 1",
                "    event_types: 2",
                "    event_types: 1",
                "    event_types: 1",
                "    event_types: 1",
                "    event_types: 2",
                "    event_types: 2",
                "    latencies_ms: 3456",
                "    latencies_ms: 267",
                "    latencies_ms: 1230",
                "    latencies_ms: 45",
                "    latencies_ms: 2111",
                "    latencies_ms: 450",
                "    latencies_ms: 638",
                "    latencies_ms: 1300",
                "    network_id <",
                "      network_id: 101",
                "    >",
                "    return_codes: 0",
                "    return_codes: 0",
                "    return_codes: 22",
                "    return_codes: 3",
                "    return_codes: 1",
                "    return_codes: 0",
                "    return_codes: 200",
                "    return_codes: 178",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testIpManagerEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(IpManagerEvent.class),
                aString("wlan0"),
                anInt(IpManagerEvent.PROVISIONING_OK),
                aLong(5678));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  ip_provisioning_event <",
                "    event_type: 1",
                "    if_name: \"wlan0\"",
                "    latency_ms: 5678",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testIpReachabilityEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(IpReachabilityEvent.class),
                aString("wlan0"),
                anInt(IpReachabilityEvent.NUD_FAILED));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  ip_reachability_event <",
                "    event_type: 512",
                "    if_name: \"wlan0\"",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testNetworkEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(NetworkEvent.class),
                anInt(100),
                anInt(5),
                aLong(20410));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  network_event <",
                "    event_type: 5",
                "    latency_ms: 20410",
                "    network_id <",
                "      network_id: 100",
                "    >",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testValidationProbeEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(ValidationProbeEvent.class),
                anInt(120),
                aLong(40730),
                anInt(ValidationProbeEvent.PROBE_HTTP),
                anInt(204));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  time_ms: 1",
                "  validation_probe_event <",
                "    latency_ms: 40730",
                "    network_id <",
                "      network_id: 120",
                "    >",
                "    probe_result: 204",
                "    probe_type: 1",
                "  >",
                ">");

        verifySerialization(want, ev);
    }

    public void testApfProgramEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(ApfProgramEvent.class),
                aLong(200),
                anInt(7),
                anInt(9),
                anInt(2048),
                anInt(3));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  apf_program_event <",
                "    current_ras: 9",
                "    drop_multicast: true",
                "    filtered_ras: 7",
                "    has_ipv4_addr: true",
                "    lifetime: 200",
                "    program_length: 2048",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testApfStatsSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(ApfStats.class),
                aLong(45000),
                anInt(10),
                anInt(2),
                anInt(2),
                anInt(1),
                anInt(2),
                anInt(4),
                anInt(2048));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  apf_statistics <",
                "    dropped_ras: 2",
                "    duration_ms: 45000",
                "    matching_ras: 2",
                "    max_program_size: 2048",
                "    parse_errors: 2",
                "    program_updates: 4",
                "    received_ras: 10",
                "    zero_lifetime_ras: 1",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    public void testRaEventSerialization() {
        ConnectivityMetricsEvent ev = describeIpEvent(
                aType(RaEvent.class),
                aLong(2000),
                aLong(400),
                aLong(300),
                aLong(-1),
                aLong(1000),
                aLong(-1));

        String want = joinLines(
                "dropped_events: 0",
                "events <",
                "  ra_event <",
                "    dnssl_lifetime: -1",
                "    prefix_preferred_lifetime: 300",
                "    prefix_valid_lifetime: 400",
                "    rdnss_lifetime: 1000",
                "    route_info_lifetime: -1",
                "    router_lifetime: 2000",
                "  >",
                "  time_ms: 1",
                ">");

        verifySerialization(want, ev);
    }

    static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
        try {
            byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input));
            IpConnectivityLog log = new IpConnectivityLog();
            MessageNano.mergeFrom(log, got);
            assertEquals(want, log.toString());
        } catch (Exception e) {
            fail(e.toString());
        }
    }

    static String joinLines(String ... elems) {
        StringBuilder b = new StringBuilder();
        for (String s : elems) {
            b.append(s);
            b.append("\n");
        }
        return b.toString();
    }
}
