/*
 *
 * 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"
	testpb "google.golang.org/grpc/test/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 := testpb.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")
	}
}
