# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# 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.
"""Utilities for App Engine apps for `gcloud tasks` commands."""


from googlecloudsdk.api_lib.app import appengine_api_client as app_engine_api
from googlecloudsdk.api_lib.tasks import GetApiAdapter
from googlecloudsdk.calliope import base as calliope_base
from googlecloudsdk.command_lib.tasks import constants
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log


class RegionResolvingError(exceptions.Error):
  """Error for when the app's region cannot be ultimately determined."""


def AppEngineAppExists():
  """Returns whether an AppEngine app exists for the current project.

  Previously we were relying on the output of ListLocations for Cloud Tasks &
  Cloud Scheduler to determine if an AppEngine exists. Previous behaviour was
  to return only one location which would be the AppEngine app location and an
  empty list otherwise if no app existed. Now with AppEngine dependency removal,
  ListLocations will return an actual list of valid regions. If an AppEngine app
  does exist, that location will be returned indexed at 0 in the result list.
  Note: We also return False if the user does not have the necessary permissions
  to determine if the project has an AppEngine app or not.

  Returns:
    Boolean representing whether an app exists or not.
  """
  app_engine_api_client = app_engine_api.GetApiClientForTrack(
      calliope_base.ReleaseTrack.GA)
  try:
    # Should raise NotFoundError if no app exists.
    app_engine_api_client.GetApplication()
    found_app = True
  except Exception:  # pylint: disable=broad-except
    found_app = False
  return found_app


def ResolveAppLocation(project_ref, locations_client=None):
  """Gets the default location from the Cloud Tasks API.

  If an AppEngine app exists, the default location is the location where the
  app exists.

  Args:
    project_ref: The project resource to look up the location for.
    locations_client: The project resource used to look up locations.

  Returns:
    The location. Some examples: 'us-central1', 'us-east4'

  Raises:
    RegionResolvingError: If we are unable to determine a default location
      for the given project.
  """
  if not locations_client:
    locations_client = GetApiAdapter(calliope_base.ReleaseTrack.GA).locations
  locations = list(locations_client.List(project_ref))
  if len(locations) >= 1 and AppEngineAppExists():
    location = locations[0].labels.additionalProperties[0].value
    if len(locations) > 1:
      log.warning(
          constants.APP_ENGINE_DEFAULT_LOCATION_WARNING.format(location))
    return location
  raise RegionResolvingError(
      'Please use the location flag to manually specify a location.')
