// TestGetInterfaces  verify that interfaces works
func TestGetInterfaces(t *testing.T) {

	var (
		d            *ICSPTest
		c            *icsp.ICSPClient
		s            icsp.Server
		serialNumber string
		err          error
	)
	if os.Getenv("ICSP_TEST_ACCEPTANCE") == "true" {
		log.Debug("implements acceptance test for TestGetInterfaces")
		d, c = getTestDriverA()
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		if os.Getenv("ONEVIEW_TEST_PROVISION") == "true" {
			serialNumber = d.Tc.GetTestData(d.Env, "FreeBladeSerialNumber").(string)
			s, err = c.GetServerBySerialNumber(serialNumber)
		} else {
			serialNumber = d.Tc.GetTestData(d.Env, "SerialNumber").(string)
			s, err = c.GetServerBySerialNumber(serialNumber)
		}
		data := s.GetInterfaces()
		assert.NoError(t, err, "GetInterfaces threw error -> %s, %+v\n", err, data)
		assert.True(t, len(data) > 0, "Failed to get a valid list of interfaces -> %+v", data)
		for _, inet := range data {
			log.Infof("inet -> %+v", inet)
			log.Infof("inet ip -> %+v", inet.IPV4Addr)
			log.Infof("inet ip -> %+v", inet.Slot)
			log.Infof("inet ip -> %+v", inet.MACAddr)
		}
	} else {
		log.Debug("implements unit test for TestGetInterfaces")
		d, c = getTestDriverU()
		jsonServerData := d.Tc.GetTestData(d.Env, "ServerJSONString").(string)
		log.Debugf("jsonServerData => %s", jsonServerData)
		err := json.Unmarshal([]byte(jsonServerData), &s)
		assert.NoError(t, err, "Unmarshal Server threw error -> %s, %+v\n", err, jsonServerData)

		log.Debugf("server -> %v", s)

		data := s.GetInterfaces()
		log.Debugf("Interfaces -> %+v", data)
		assert.True(t, len(data) > 0, "Failed to get a valid list of interfaces -> %+v", data)
		for _, inet := range data {
			log.Debugf("inet -> %+v", inet)
			log.Debugf("inet ip -> %+v", inet.IPV4Addr)
			log.Debugf("inet ip -> %+v", inet.Slot)
			log.Debugf("inet ip -> %+v", inet.MACAddr)
		}
	}
}
// Test getting a valueitems from customattribute
func TestGetValueItems(t *testing.T) {
	var (
		d *ICSPTest
		s icsp.Server
	)
	d, _ = getTestDriverU()
	jsonServerData := d.Tc.GetTestData(d.Env, "ServerJSONString").(string)
	log.Debugf("jsonServerData => %s", jsonServerData)
	err := json.Unmarshal([]byte(jsonServerData), &s)
	assert.NoError(t, err, "Unmarshal Server threw error -> %s, %+v\n", err, jsonServerData)

	testKey1 := d.Tc.GetTestData(d.Env, "KeyTest1").(string)
	_, vi := s.GetValueItems(testKey1)
	assert.Equal(t, 1, len(vi), "Should find 1 valueitem")
}
// TestSetValueItems
func TestSetValueItems(t *testing.T) {
	var (
		d *ICSPTest
		s icsp.Server
	)
	d, _ = getTestDriverU()
	jsonServerData := d.Tc.GetTestData(d.Env, "ServerJSONString").(string)
	log.Debugf("jsonServerData => %s", jsonServerData)
	err := json.Unmarshal([]byte(jsonServerData), &s)
	assert.NoError(t, err, "Unmarshal Server threw error -> %s, %+v\n", err, jsonServerData)

	// Try setting a ValueItem that doesn't exist
	s.SetValueItems("foo", icsp.ValueItem{Scope: "server", Value: "bar"})
	_, v := s.GetValueItem("foo", "server")
	assert.Equal(t, "bar", v.Value, "Should find bar from key foo")

}
// TestGetInterfaceFromMac verify that getting an inerface with mac address works
func TestGetInterfaceFromMac(t *testing.T) {
	var (
		d            *ICSPTest
		c            *icsp.ICSPClient
		s            icsp.Server
		serialNumber string
		macAddr      string
		err          error
		data         icsp.Interface
	)
	if os.Getenv("ICSP_TEST_ACCEPTANCE") == "true" {
		log.Debug("implements acceptance test for TestGetInterfaceFromMac")
		d, c = getTestDriverA()
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		if os.Getenv("ONEVIEW_TEST_PROVISION") == "true" {
			serialNumber = d.Tc.GetTestData(d.Env, "FreeBladeSerialNumber").(string)
			macAddr = d.Tc.GetTestData(d.Env, "FreeMacAddr").(string)
			s, err = c.GetServerBySerialNumber(serialNumber)
		} else {
			serialNumber = d.Tc.GetTestData(d.Env, "SerialNumber").(string)
			macAddr = d.Tc.GetTestData(d.Env, "MacAddr").(string)
			s, err = c.GetServerBySerialNumber(serialNumber)
		}

		s, err = c.GetServerBySerialNumber(serialNumber)
		assert.NoError(t, err, "GetServerBySerialNumber threw error -> %s, %+v\n", err, serialNumber)

		log.Debugf("server -> %v", s)
		data, err = s.GetInterfaceFromMac(macAddr)
		assert.NoError(t, err, "GetInterfaceFromMac threw error -> %s, %+v\n", err, data)
		assert.Equal(t, macAddr, data.MACAddr, "Failed to get interface -> %+v", data)
		log.Infof("Found interface -> %+v", data)
	} else {
		log.Debug("implements unit test for TestGetInterfaces")
		d, c = getTestDriverU()
		jsonServerData := d.Tc.GetTestData(d.Env, "ServerJSONString").(string)
		log.Debugf("jsonServerData => %s", jsonServerData)
		err := json.Unmarshal([]byte(jsonServerData), &s)
		assert.NoError(t, err, "Unmarshal Server threw error -> %s, %+v\n", err, jsonServerData)
		// macAddr = d.Tc.GetTestData(d.Env, "ServerMacAddr").(string)
		// TODO: find a way to unit test this
	}

}
// TestGetValueItem gets a valueitem with scope
func TestGetValueItem(t *testing.T) {
	var (
		d *ICSPTest
		s icsp.Server
	)
	d, _ = getTestDriverU()
	jsonServerData := d.Tc.GetTestData(d.Env, "ServerJSONString").(string)
	log.Debugf("jsonServerData => %s", jsonServerData)
	err := json.Unmarshal([]byte(jsonServerData), &s)
	assert.NoError(t, err, "Unmarshal Server threw error -> %s, %+v\n", err, jsonServerData)

	testKey1 := d.Tc.GetTestData(d.Env, "KeyTest1").(string)
	testScope1 := d.Tc.GetTestData(d.Env, "ScopeTest1").(string)
	expectsValue1 := d.Tc.GetExpectsData(d.Env, "ValueTest1").(string)

	_, v := s.GetValueItem(testKey1, testScope1)
	assert.Equal(t, expectsValue1, v.Value, "Should find ValueItem")
}
// TestSetCustomAttribute
func TestSetCustomAttribute(t *testing.T) {
	var (
		d *ICSPTest
		s icsp.Server
	)
	// unit test case
	d, _ = getTestDriverU()
	jsonServerData := d.Tc.GetTestData(d.Env, "ServerJSONString").(string)
	log.Debugf("jsonServerData => %s", jsonServerData)
	err := json.Unmarshal([]byte(jsonServerData), &s)
	assert.NoError(t, err, "Unmarshal Server threw error -> %s, %+v\n", err, jsonServerData)

	testKey1 := d.Tc.GetTestData(d.Env, "KeyTest1").(string)
	testScope1 := d.Tc.GetTestData(d.Env, "ScopeTest1").(string)
	expectsValue1 := d.Tc.GetExpectsData(d.Env, "ValueTest1").(string)

	// complete test case 1, simple read of custom attributes
	_, testValue1 := s.GetValueItem(testKey1, testScope1)
	assert.Equal(t, expectsValue1, testValue1.Value, "Should return testcase 1 simple read")
	// TODO: test case 2 , setting a value on existing attribute
	testKey2 := d.Tc.GetTestData(d.Env, "KeyTest2Existing").(string)
	testScope2 := d.Tc.GetTestData(d.Env, "ScopeTest2Existing").(string)
	testValueNew2 := d.Tc.GetTestData(d.Env, "ValueTest2ExistingNew").(string)
	expectsValueOld2 := d.Tc.GetExpectsData(d.Env, "ValueTestOld2").(string)
	expectsValueNew2 := d.Tc.GetExpectsData(d.Env, "ValueTestNew2").(string)

	_, testValue2 := s.GetValueItem(testKey2, testScope2)
	assert.Equal(t, expectsValueOld2, testValue2.Value, "Should return testcase 2 old setting existing attribute")

	s.SetCustomAttribute(testKey2, testScope2, testValueNew2)
	_, testValue2 = s.GetValueItem(testKey2, testScope2)
	assert.Equal(t, expectsValueNew2, testValue2.Value, "Should return testcase 2 new setting existing attribute")

	// TODO: test case 3, appending a new attribute
	testKey3 := d.Tc.GetTestData(d.Env, "KeyTest3New").(string)
	testScope3 := d.Tc.GetTestData(d.Env, "ScopeTest3New").(string)
	testValue3New := d.Tc.GetTestData(d.Env, "ValueTest3New").(string)
	expectsValue3 := d.Tc.GetExpectsData(d.Env, "ValueTest3").(string)

	i, _ := s.GetValueItem(testKey3, testScope3)
	assert.Equal(t, -1, i, "Should not find test case 3 value")

	s.SetCustomAttribute(testKey3, testScope3, testValue3New)
	_, testValue3 := s.GetValueItem(testKey3, testScope3)
	assert.Equal(t, expectsValue3, testValue3.Value, "Should return testcase 3 result")
}