// Copyright (C) 2023 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/>.

part of 'exceptions.dart';

/// {@macro apply_action_code_failure}
class ApplyActionCodeFailureBase extends ApplyActionCodeFailureInterface {
  ApplyActionCodeFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  ApplyActionCodeFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'expired-action-code':
        msg = 'Action code has expired.';
        break;
      case 'invalid-action-code':
        msg = 'Action code is invalid.';
        break;
      case 'user-disabled':
        msg = 'This user has been disabled. Please contact support for help.';
        break;
      case 'user-not-found':
        msg = 'Email is not found, please create an account.';
        break;

      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro sign_up_with_email_and_password_failure}
class SignUpWithEmailAndPasswordFailureBase
    extends SignUpWithEmailAndPasswordFailureInterface {
  SignUpWithEmailAndPasswordFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  SignUpWithEmailAndPasswordFailureBase.fromCode(String code)
      : super.fromCode(code) {
    switch (code) {
      case 'invalid-email':
        msg = 'The email address is badly formatted.';
        break;
      case 'user-disabled':
        msg = 'This user has been disabled. Please contact support for help.';
        break;
      case 'email-already-in-use':
        msg = 'An account already exists for that email.';
        break;
      case 'operation-not-allowed':
        msg = 'Operation is not allowed. Please contact support.';
        break;
      case 'weak-password':
        msg = 'Please enter a stronger password.';
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro fetch_sign_in_methods_failure}
class FetchSignInMethodsForEmailFailureBase
    extends FetchSignInMethodsForEmailFailureInterface {
  FetchSignInMethodsForEmailFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  FetchSignInMethodsForEmailFailureBase.fromCode(String code)
      : super.fromCode(code) {
    switch (code) {
      case 'invalid-email':
        msg = 'The email address is badly formatted.';
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro sign_in_anonymously_failure}
class SignInAnonymouslyFailureBase extends SignInAnonymouslyFailureInterface {
  SignInAnonymouslyFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  SignInAnonymouslyFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'operation-not-allowed':
        msg = 'Operation is not allowed. Please contact support.';
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro sign_in_with_credential_failure}
class SignInWithCredentialFailureBase
    extends SignInWithCredentialFailureInterface {
  SignInWithCredentialFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  SignInWithCredentialFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'account-exists-with-different-credential':
        msg = 'Account exists with different credentials.';
        break;
      case 'invalid-credential':
        msg = 'The credential received is malformed or has expired.';
        break;
      case 'operation-not-allowed':
        msg = 'Operation is not allowed. Please contact support.';
        break;
      case 'user-disabled':
        msg = 'This user has been disabled. Please contact support for help.';
        break;
      case 'user-not-found':
        msg = 'Email is not found, please create an account.';
        break;
      case 'wrong-password':
        msg = 'Incorrect password, please try again.';
        break;
      case 'invalid-verification-code':
        msg = 'The credential verification code received is invalid.';
        break;
      case 'invalid-verification-id':
        msg = 'The credential verification ID received is invalid.';
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro sign_in_with_google_failure}
class SignInWithGoogleFailureBase extends SignInWithCredentialFailureBase
    implements SignInWithGoogleFailureInterface {
  SignInWithGoogleFailureBase([super.code, super.msg]);
  SignInWithGoogleFailureBase.fromCode(super.code) : super.fromCode();
}

/// {@macro sign_in_with_facebook_failure}
class SignInWithFacebookFailureBase extends SignInWithCredentialFailureBase
    implements SignInWithFacebookFailureInterface {
  SignInWithFacebookFailureBase([super.code, super.msg]);
  SignInWithFacebookFailureBase.fromCode(super.code) : super.fromCode();
}

/// {@macro sign_in_with_apple_failure}
class SignInWithAppleFailureBase extends SignInWithCredentialFailureBase
    implements SignInWithAppleFailureInterface {
  SignInWithAppleFailureBase([super.code, super.msg]);
  SignInWithAppleFailureBase.fromCode(super.code) : super.fromCode();
}

/// {@macro sign_in_with_twitter_failure}
class SignInWithTwitterFailureBase extends SignInWithCredentialFailureBase
    implements SignInWithAppleFailureInterface {
  SignInWithTwitterFailureBase([super.code, super.msg]);
  SignInWithTwitterFailureBase.fromCode(super.code) : super.fromCode();
}

/// {@macro sign_in_with_email_link_failure}
class SignInWithEmailLinkFailureBase
    extends SignInWithEmailLinkFailureInterface {
  SignInWithEmailLinkFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  SignInWithEmailLinkFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'expired-action-code':
        msg = 'Action code has expired.';
        break;
      case 'invalid-email':
        msg = 'Email is not valid or badly formatted.';
        break;
      case 'user-disabled':
        msg = 'This user has been disabled. Please contact support for help.';
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro sign_in_with_email_and_password_failure}
class SignInWithEmailAndPasswordFailureBase
    extends SignInWithEmailAndPasswordFailureInterface {
  SignInWithEmailAndPasswordFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  SignInWithEmailAndPasswordFailureBase.fromCode(String code)
      : super.fromCode(code) {
    switch (code) {
      case 'invalid-email':
        msg = 'Email is not valid or badly formatted.';
        break;
      case 'user-disabled':
        msg = 'This user has been disabled. Please contact support for help.';
        break;
      case 'user-not-found':
        msg = 'Email is not found, please create an account.';
        break;
      case 'wrong-password':
        msg = 'Incorrect password, please try again.';
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro send_email_verification_failure}
class SendEmailVerificationFailureBase
    extends SendEmailVerificationFailureInterface {
  SendEmailVerificationFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');

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

/// {@macro send_password_reset_email_failure}
class SendPasswordResetEmailFailureBase
    extends SendPasswordResetEmailFailureInterface {
  SendPasswordResetEmailFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  SendPasswordResetEmailFailureBase.fromCode(super.code) : super.fromCode();
}

/// {@macro send_sign_in_link_email_failure}
class SendSignInLinkEmailFailureBase
    extends SendSignInLinkEmailFailureInterface {
  SendSignInLinkEmailFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');

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

/// {@macro confirm_password_reset_failure}
class ConfirmPasswordResetFailureBase
    extends ConfirmPasswordResetFailureInterface {
  ConfirmPasswordResetFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');

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

/// {@macro verify_password_reset_code_failure}
class VerifyPasswordResetCodeFailureBase
    extends VerifyPasswordResetCodeFailureInterface {
  VerifyPasswordResetCodeFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');

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

/// {@macro refresh_failure}
class RefreshFailureBase extends RefreshFailureInterface {
  RefreshFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  RefreshFailureBase.fromCode(super.code) : super.fromCode();
}

/// {@macro sign_out_failure}
class SignOutFailureBase extends SignOutFailureInterface {
  SignOutFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');

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

/// {@macro reauthenticate_failure}
class ReauthenticateFailureBase extends ReauthenticateFailureInterface {
  ReauthenticateFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  ReauthenticateFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'user-mismatch':
        msg = 'Given credential does not correspond to the user.';
        break;
      case 'user-not-found':
        msg = 'User is not found, please create an account.';
        break;
      case 'invalid-credential':
        msg = 'The credential received is malformed or has expired.';
        break;
      case 'invalid-email':
        msg = 'Email is not valid or badly formatted.';
        break;
      case 'wrong-password':
        msg = 'Incorrect password, please try again.';
        break;
      case 'invalid-verification-code':
        msg = 'The credential verification code received is invalid.';
        break;
      case 'invalid-verification-id':
        msg = 'The credential verification ID received is invalid.';
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro update_email_failure}
class UpdateEmailFailureBase extends UpdateEmailFailureInterface {
  UpdateEmailFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  UpdateEmailFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'invalid-email':
        msg = 'Email is not valid or badly formatted.';
        break;
      case 'email-already-in-use':
        msg = 'An account already exists for that email.';
        break;
      case 'requires-recent-login':
        msg = "User's last sign-in time does not meet the security threshold.";
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro update_password_failure}
class UpdatePasswordFailureBase extends UpdatePasswordFailureInterface {
  UpdatePasswordFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
  UpdatePasswordFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'weak-password':
        msg = 'Please enter a stronger password.';
        break;
      case 'requires-recent-login':
        msg = "User's last sign-in time does not meet the security threshold.";
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}

/// {@macro model_parsing_failure}
class ModelParsingFailureBase extends ModelParsingFailureInterface {
  ModelParsingFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');

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

/// {@macro delete_account_failure}
class DeleteAccountFailureBase extends DeleteAccountFailureInterface {
  DeleteAccountFailureBase([String? code, String? msg])
      : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');

  DeleteAccountFailureBase.fromCode(String code) : super.fromCode(code) {
    switch (code) {
      case 'requires-recent-login':
        msg = "User's last sign-in time does not meet the security threshold.";
        break;
      default:
        this.code = 'unknown';
        msg = 'An unknown error occurred.';
    }
  }
}
