# -*- coding: utf-8 -*-
# Copyright 2021 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License")
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""API handlers for user authentication and session creation via Google Sign-In."""

import google.oauth2.id_token
import werkzeug.exceptions
from chromestatus_openapi.models import SignInRequest
from google.auth.transport import requests

import settings
from framework import basehandlers, users


class LoginAPI(basehandlers.APIHandler):
    """Create a session using the credential generated by Sign-In With Google."""

    def do_get(self, **kwargs):
        """Reject unneeded GET requests without triggering Error Reporting."""
        self.abort(405, valid_methods=['POST'])

    def do_post(self, **kwargs):
        """Sign in the user."""
        try:
            request = SignInRequest.from_dict(self.request.json)
            token = request.credential
            if not token:
                raise werkzeug.exceptions.BadRequest(
                    description="Missing required field 'credential'"
                )  # noqa: E501
            message = 'Unable to Authenticate. Please sign in again.'
        except ValueError:
            message = 'Invalid Request'

        try:
            idinfo = google.oauth2.id_token.verify_oauth2_token(
                token, requests.Request(), settings.GOOGLE_SIGN_IN_CLIENT_ID
            )
            users.add_signed_user_info_to_session(idinfo['email'])
            self._update_last_visit_field(idinfo['email'])
            message = 'Done'
            # print(idinfo['email'], file=sys.stderr)
        except ValueError:
            message = 'Invalid token'

        return {'message': message}


TESTING_ACCOUNTS = ['example@chromium.org']


class MockLogin(basehandlers.APIHandler):
    """Create a session using a testing account."""

    def do_post(self, **kwargs):
        """Mock sign in."""
        if not settings.DEV_MODE and not settings.UNIT_TEST_MODE:
            self.abort(
                status=403,
                msg='This can only be used in a development environment.',
            )

        email = self.get_param('email', default=TESTING_ACCOUNTS[0])
        if email not in TESTING_ACCOUNTS:
            self.abort(
                status=403,
                msg='This can only be used with specific testing accounts.',
            )

        users.add_signed_user_info_to_session(email)
        return {'message': f'Signed in as {email}'}
