// 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_);
}

TEST_F(SupplicantEAPStateHandlerTest, ParameterNeededPin) {
  StartEAP();
  EXPECT_FALSE(handler_.ParseStatus(
      WPASupplicant::kEAPStatusParameterNeeded,
      WPASupplicant::kEAPRequestedParameterPIN,
      &failure_));
  EXPECT_TRUE(handler_.is_eap_in_progress());
  EXPECT_EQ("", GetTLSError());
  EXPECT_EQ(Service::kFailurePinMissing, failure_);
}

}  // namespace shill
