/*
 *
 * Copyright 2018 gRPC authors.
 *
 * 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.
 *
 */

// The test in this file should be run in an environment that has go1.10 or later,
// as the function SyscallConn() (required to get socket option) was
// introduced to net.TCPListener in go1.10.

package test

import (
	"testing"
	"time"

	"google.golang.org/grpc/internal/channelz"

	testgrpc "google.golang.org/grpc/interop/grpc_testing"
)

func (s) TestCZSocketMetricsSocketOption(t *testing.T) {
	envs := []env{tcpClearRREnv, tcpTLSRREnv}
	for _, e := range envs {
		testCZSocketMetricsSocketOption(t, e)
	}
}

func testCZSocketMetricsSocketOption(t *testing.T, e env) {
	czCleanup := channelz.NewChannelzStorageForTesting()
	defer czCleanupWrapper(czCleanup, t)
	te := newTest(t, e)
	te.startServer(&testServer{security: e.security})
	defer te.tearDown()
	cc := te.clientConn()
	tc := testgrpc.NewTestServiceClient(cc)
	doSuccessfulUnaryCall(tc, t)

	time.Sleep(10 * time.Millisecond)
	ss, _ := channelz.GetServers(0, 0)
	if len(ss) != 1 {
		t.Fatalf("There should be one server, not %d", len(ss))
	}
	if len(ss[0].ListenSockets) != 1 {
		t.Fatalf("There should be one listen socket, not %d", len(ss[0].ListenSockets))
	}
	for id := range ss[0].ListenSockets {
		sm := channelz.GetSocket(id)
		if sm == nil || sm.SocketData == nil || sm.SocketData.SocketOptions == nil {
			t.Fatalf("Unable to get server listen socket options")
		}
	}
	ns, _ := channelz.GetServerSockets(ss[0].ID, 0, 0)
	if len(ns) != 1 {
		t.Fatalf("There should be one server normal socket, not %d", len(ns))
	}
	if ns[0] == nil || ns[0].SocketData == nil || ns[0].SocketData.SocketOptions == nil {
		t.Fatalf("Unable to get server normal socket options")
	}

	tchan, _ := channelz.GetTopChannels(0, 0)
	if len(tchan) != 1 {
		t.Fatalf("There should only be one top channel, not %d", len(tchan))
	}
	if len(tchan[0].SubChans) != 1 {
		t.Fatalf("There should only be one subchannel under top channel %d, not %d", tchan[0].ID, len(tchan[0].SubChans))
	}
	var id int64
	for id = range tchan[0].SubChans {
		break
	}
	sc := channelz.GetSubChannel(id)
	if sc == nil {
		t.Fatalf("There should only be one socket under subchannel %d, not 0", id)
	}
	if len(sc.Sockets) != 1 {
		t.Fatalf("There should only be one socket under subchannel %d, not %d", sc.ID, len(sc.Sockets))
	}
	for id = range sc.Sockets {
		break
	}
	skt := channelz.GetSocket(id)
	if skt == nil || skt.SocketData == nil || skt.SocketData.SocketOptions == nil {
		t.Fatalf("Unable to get client normal socket options")
	}
}
