// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'package:wyatt_architecture/wyatt_architecture.dart';

part 'exceptions_firebase.dart';

abstract class AuthenticationFailureInterface extends AppException
    implements Exception {
  AuthenticationFailureInterface(this.code, this.msg);
  AuthenticationFailureInterface.fromCode(this.code)
      : msg = 'An unknown error occurred.';
  String code;
  String msg;

  @override
  String get message => msg;
}

/// {@template apply_action_code_failure}
/// Thrown if during the apply action code process if a failure occurs.
/// {@endtemplate}
abstract class ApplyActionCodeFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro apply_action_code_failure}
  ApplyActionCodeFailureInterface(super.code, super.msg);

  /// {@macro apply_action_code_failure}
  ApplyActionCodeFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_up_with_email_and_password_failure}
/// Thrown if during the sign up process if a failure occurs.
/// {@endtemplate}
abstract class SignUpWithEmailAndPasswordFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_up_with_email_and_password_failure}
  SignUpWithEmailAndPasswordFailureInterface(super.code, super.msg);

  /// {@macro sign_up_with_email_and_password_failure}
  SignUpWithEmailAndPasswordFailureInterface.fromCode(super.code)
      : super.fromCode();
}

/// {@template fetch_sign_in_methods_failure}
/// Thrown during the fetch sign in methods if a failure occurs.
/// {@endtemplate}
abstract class FetchSignInMethodsForEmailFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro fetch_sign_in_methods_failure}
  FetchSignInMethodsForEmailFailureInterface(super.code, super.msg);

  /// {@macro fetch_sign_in_methods_failure}
  FetchSignInMethodsForEmailFailureInterface.fromCode(super.code)
      : super.fromCode();
}

/// {@template sign_in_with_credential_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInWithCredentialFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_with_credential_failure}
  SignInWithCredentialFailureInterface(super.code, super.msg);

  /// {@macro sign_in_with_credential_failure}
  SignInWithCredentialFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_in_anonymously_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInAnonymouslyFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_anonymously_failure}
  SignInAnonymouslyFailureInterface(super.code, super.msg);

  /// {@macro sign_in_anonymously_failure}
  SignInAnonymouslyFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_in_with_google_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInWithGoogleFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_with_google_failure}
  SignInWithGoogleFailureInterface(super.code, super.msg);

  /// {@macro sign_in_with_google_failure}
  SignInWithGoogleFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_in_with_facebook_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInWithFacebookFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_with_facebook_failure}
  SignInWithFacebookFailureInterface(super.code, super.msg);

  /// {@macro sign_in_with_facebook_failure}
  SignInWithFacebookFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_in_with_apple_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInWithAppleFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_with_apple_failure}
  SignInWithAppleFailureInterface(super.code, super.msg);

  /// {@macro sign_in_with_apple_failure}
  SignInWithAppleFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_in_with_twitter_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInWithTwitterFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_with_twitter_failure}
  SignInWithTwitterFailureInterface(super.code, super.msg);

  /// {@macro sign_in_with_twitter_failure}
  SignInWithTwitterFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_in_with_email_link_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInWithEmailLinkFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_with_email_link_failure}
  SignInWithEmailLinkFailureInterface(super.code, super.msg);

  /// {@macro sign_in_with_email_link_failure}
  SignInWithEmailLinkFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_in_with_email_and_password_failure}
/// Thrown during the sign in process if a failure occurs.
/// {@endtemplate}
abstract class SignInWithEmailAndPasswordFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro sign_in_with_email_and_password_failure}
  SignInWithEmailAndPasswordFailureInterface(super.code, super.msg);

  /// {@macro sign_in_with_email_and_password_failure}
  SignInWithEmailAndPasswordFailureInterface.fromCode(super.code)
      : super.fromCode();
}

/// {@template send_email_verification_failure}
/// Thrown during the email verification process if a failure occurs.
/// {@endtemplate}
abstract class SendEmailVerificationFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro send_email_verification_failure}
  SendEmailVerificationFailureInterface(super.code, super.msg);

  /// {@macro send_email_verification_failure}
  SendEmailVerificationFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template send_password_reset_email_failure}
/// Thrown during the password reset process if a failure occurs.
/// {@endtemplate}
abstract class SendPasswordResetEmailFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro send_password_reset_email_failure}
  SendPasswordResetEmailFailureInterface(super.code, super.msg);

  /// {@macro send_password_reset_email_failure}
  SendPasswordResetEmailFailureInterface.fromCode(super.code)
      : super.fromCode();
}

/// {@template send_sign_in_link_email_failure}
/// Thrown during the sign in link process if a failure occurs.
/// {@endtemplate}
abstract class SendSignInLinkEmailFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro send_sign_in_link_email_failure}
  SendSignInLinkEmailFailureInterface(super.code, super.msg);

  /// {@macro send_sign_in_link_email_failure}
  SendSignInLinkEmailFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template confirm_password_reset_failure}
/// Thrown during the password reset process if a failure occurs.
/// {@endtemplate}
abstract class ConfirmPasswordResetFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro confirm_password_reset_failure}
  ConfirmPasswordResetFailureInterface(super.code, super.msg);

  /// {@macro confirm_password_reset_failure}
  ConfirmPasswordResetFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template verify_password_reset_code_failure}
/// Thrown during the password reset process if a failure occurs.
/// {@endtemplate}
abstract class VerifyPasswordResetCodeFailureInterface
    extends AuthenticationFailureInterface {
  /// {@macro verify_password_reset_code_failure}
  VerifyPasswordResetCodeFailureInterface(super.code, super.msg);

  /// {@macro verify_password_reset_code_failure}
  VerifyPasswordResetCodeFailureInterface.fromCode(super.code)
      : super.fromCode();
}

/// {@template refresh_failure}
/// Thrown during the refresh process if a failure occurs.
/// {@endtemplate}
abstract class RefreshFailureInterface extends AuthenticationFailureInterface {
  /// {@macro refresh_failure}
  RefreshFailureInterface(super.code, super.msg);

  /// {@macro refresh_failure}
  RefreshFailureInterface.fromCode(super.code) : super.fromCode();
}

/// {@template sign_out_failure}
/// Thrown during the sign out process if a failure occurs.
/// {@endtemplate}
abstract class SignOutFailureInterface extends AuthenticationFailureInterface {
  /// {@macro sign_out_failure}
  SignOutFailureInterface(super.code, super.msg);

  /// {@macro sign_out_failure}
  SignOutFailureInterface.fromCode(super.code) : super.fromCode();
}

abstract class GetIdTokenFailureInterface
    extends AuthenticationFailureInterface {
  GetIdTokenFailureInterface(super.code, super.msg);

  GetIdTokenFailureInterface.fromCode(super.code) : super.fromCode();
}

abstract class ReauthenticateFailureInterface
    extends AuthenticationFailureInterface {
  ReauthenticateFailureInterface(super.code, super.msg);

  ReauthenticateFailureInterface.fromCode(super.code) : super.fromCode();
}

abstract class UpdateEmailFailureInterface
    extends AuthenticationFailureInterface {
  UpdateEmailFailureInterface(super.code, super.msg);

  UpdateEmailFailureInterface.fromCode(super.code) : super.fromCode();
}

abstract class UpdatePasswordFailureInterface
    extends AuthenticationFailureInterface {
  UpdatePasswordFailureInterface(super.code, super.msg);

  UpdatePasswordFailureInterface.fromCode(super.code) : super.fromCode();
}

abstract class ModelParsingFailureInterface
    extends AuthenticationFailureInterface {
  ModelParsingFailureInterface(super.code, super.msg);

  ModelParsingFailureInterface.fromCode(super.code) : super.fromCode();
}
