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

#include "shill/supplicant_eap_state_handler.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/mock_log.h"
#include "shill/wpa_supplicant.h"

using std::string;
using testing::_;
using testing::EndsWith;
using testing::Mock;

namespace shill {

class SupplicantEAPStateHandlerTest : public testing::Test {
 public:
  SupplicantEAPStateHandlerTest() : failure_(Service::kFailureUnknown) {}
  virtual ~SupplicantEAPStateHandlerTest() {}

 protected:
  void StartEAP() {
    EXPECT_CALL(log_, Log(logging::LOG_INFO, _,
                          EndsWith("Authentication starting.")));
    EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusStarted, "",
                                      &failure_));
    Mock::VerifyAndClearExpectations(&log_);
  }

  const string &GetTLSError() { return handler_.tls_error_; }

  SupplicantEAPStateHandler handler_;
  Service::ConnectFailure failure_;
  ScopedMockLog log_;
};

TEST_F(SupplicantEAPStateHandlerTest, Construct) {
  EXPECT_FALSE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
}

TEST_F(SupplicantEAPStateHandlerTest, AuthenticationStarting) {
  StartEAP();
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
  EXPECT_EQ(Service::kFailureUnknown, failure_);
}

TEST_F(SupplicantEAPStateHandlerTest, AcceptedMethod) {
  StartEAP();
  const string kEAPMethod("EAP-ROCHAMBEAU");
  EXPECT_CALL(log_, Log(logging::LOG_INFO, _,
                        EndsWith("accepted method " + kEAPMethod)));
  EXPECT_FALSE(handler_.ParseStatus(
      WPASupplicant::kEAPStatusAcceptProposedMethod, kEAPMethod, &failure_));
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
  EXPECT_EQ(Service::kFailureUnknown, failure_);
}

TEST_F(SupplicantEAPStateHandlerTest, SuccessfulCompletion) {
  StartEAP();
  EXPECT_CALL(log_, Log(_, _,
                        EndsWith("Completed authentication successfully.")));
  EXPECT_TRUE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
                                   WPASupplicant::kEAPParameterSuccess,
                                   &failure_));
  EXPECT_FALSE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
  EXPECT_EQ(Service::kFailureUnknown, failure_);
}

TEST_F(SupplicantEAPStateHandlerTest, EAPFailureGeneric) {
  StartEAP();
  // An EAP failure without a previous TLS indication yields a generic failure.
  EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
                                    WPASupplicant::kEAPParameterFailure,
                                    &failure_));

  // Since it hasn't completed successfully, we must assume even in failure
  // that wpa_supplicant is continuing the EAP authentication process.
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
  EXPECT_EQ(Service::kFailureEAPAuthentication, failure_);
}

TEST_F(SupplicantEAPStateHandlerTest, EAPFailureLocalTLSIndication) {
  StartEAP();
  // A TLS indication should be stored but a failure should not be returned.
  EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusLocalTLSAlert, "",
                                    &failure_));
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ(WPASupplicant::kEAPStatusLocalTLSAlert, GetTLSError());
  EXPECT_EQ(Service::kFailureUnknown, failure_);

  // An EAP failure with a previous TLS indication yields a specific failure.
  EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
                                    WPASupplicant::kEAPParameterFailure,
                                    &failure_));
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ(Service::kFailureEAPLocalTLS, failure_);
}

TEST_F(SupplicantEAPStateHandlerTest, EAPFailureRemoteTLSIndication) {
  StartEAP();
  // A TLS indication should be stored but a failure should not be returned.
  EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusRemoteTLSAlert, "",
                                    &failure_));
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ(WPASupplicant::kEAPStatusRemoteTLSAlert, GetTLSError());
  EXPECT_EQ(Service::kFailureUnknown, failure_);

  // An EAP failure with a previous TLS indication yields a specific failure.
  EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
                                    WPASupplicant::kEAPParameterFailure,
                                    &failure_));
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ(Service::kFailureEAPRemoteTLS, failure_);
}


TEST_F(SupplicantEAPStateHandlerTest, BadRemoteCertificateVerification) {
  StartEAP();
  const string kStrangeParameter("ennui");
  EXPECT_CALL(log_, Log(logging::LOG_ERROR, _,EndsWith(
      string("Unexpected ") +
      WPASupplicant::kEAPStatusRemoteCertificateVerification +
      " parameter: " + kStrangeParameter)));
  EXPECT_FALSE(handler_.ParseStatus(
      WPASupplicant::kEAPStatusRemoteCertificateVerification, kStrangeParameter,
      &failure_));
  // Although we reported an error, this shouldn't mean failure.
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
  EXPECT_EQ(Service::kFailureUnknown, failure_);
}

TEST_F(SupplicantEAPStateHandlerTest, ParameterNeeded) {
  StartEAP();
  const string kAuthenticationParameter("nudge nudge say no more");
  EXPECT_CALL(log_, Log(logging::LOG_ERROR, _,EndsWith(
      string("aborted due to missing authentication parameter: ") +
      kAuthenticationParameter)));
  EXPECT_FALSE(handler_.ParseStatus(
      WPASupplicant::kEAPStatusParameterNeeded, kAuthenticationParameter,
      &failure_));
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
  EXPECT_EQ(Service::kFailureEAPAuthentication, failure_);
}

}  // namespace shill
