# -*- coding: utf-8 -*- #
# Copyright 2015 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.

"""Command to assist user in submitting feedback about gcloud.

Does one of two things:

1. If invoked in the context of a recent gcloud crash (i.e. an exception that
was not caught anywhere in the Cloud SDK), will direct the user to the Cloud SDK
bug tracker, with a partly pre-filled form.

2. Otherwise, directs the user to either the Cloud SDK bug tracker,
or the Cloud SDK groups page.
"""


import datetime
import textwrap

from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib import feedback_util
from googlecloudsdk.command_lib import info_holder
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
from googlecloudsdk.core.util import files
from googlecloudsdk.core.util import text as text_util

import six
from six.moves import map


GROUPS_PAGE_URL = ('https://groups.google.com/forum/?fromgroups#!forum/'
                   'google-cloud-dev')


FEEDBACK_MESSAGE = """\

We appreciate your feedback.

For general feedback, use our groups page
[{0}],
or send a mail to [google-cloud-dev@googlegroups.com].
""".format(GROUPS_PAGE_URL)


FEEDBACK_PROMPT = """\
Would you like to file a bug using our issue tracker site at [{0}] \
(will open a new browser tab)?\
""".format(feedback_util.ISSUE_TRACKER_URL)


def _PrintQuiet(info_str, log_data):
  """Print message referring to various feedback resources for quiet execution.

  Args:
    info_str: str, the output of `gcloud info`
    log_data: info_holder.LogData, log data for the provided log file
  """
  if log_data:
    if not log_data.traceback:
      log.Print(('Please consider including the log file [{0}] in any '
                 'feedback you submit.').format(log_data.filename))

  log.Print(textwrap.dedent("""\

      For general feedback, use our groups page
      [{0}], or
      send a mail to [google-cloud-dev@googlegroups.com].

      If you have found a bug, file it using our issue tracker site at
      [{1}].

      Please include the following information when filing a bug report:\
      """).format(GROUPS_PAGE_URL, feedback_util.ISSUE_TRACKER_URL))
  divider = feedback_util.GetDivider()
  log.Print(divider)
  if log_data and log_data.traceback:
    log.Print(log_data.traceback)
  log.Print(info_str.strip())
  log.Print(divider)


def _SuggestIncludeRecentLogs():
  recent_runs = info_holder.LogsInfo().GetRecentRuns()
  if recent_runs:
    now = datetime.datetime.now()
    def _FormatLogData(run):
      crash = ' (crash detected)' if run.traceback else ''
      time = 'Unknown time'
      if run.date:
        time = text_util.PrettyTimeDelta(now - run.date) + ' ago'
      return '[{0}]{1}: {2}'.format(run.command, crash, time)
    idx = console_io.PromptChoice(
        list(map(_FormatLogData, recent_runs)) + ['None of these'], default=0,
        message=('Which recent gcloud invocation would you like to provide '
                 'feedback about? This will open a new browser tab.'))
    if idx < len(recent_runs):
      return recent_runs[idx]


@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Feedback(base.Command):
  """Provide feedback to the Google Cloud CLI team.

  The Google Cloud CLI team offers support through a number of channels:

  * Google Cloud CLI Issue Tracker
  * google-cloud-dev Google group

  This command lists the available channels and facilitates getting help through
  one of them by opening a web browser to the relevant page, possibly with
  information relevant to the current install and configuration pre-populated in
  form fields on that page.
  """

  detailed_help = {
      'EXAMPLES': """
          To send feedback, including the log file for the most recent command,
          run:

            $ {command}

          To send feedback with a previously generated log file named
          'my-logfile', run:

            $ {command} --log-file=my-logfile
          """,
  }

  category = base.SDK_TOOLS_CATEGORY

  @staticmethod
  def Args(parser):
    parser.add_argument(
        '--log-file',
        help='Path to the log file from a prior gcloud run.')

  def Run(self, args):
    info = info_holder.InfoHolder(anonymizer=info_holder.Anonymizer())
    log_data = None
    if args.log_file:
      try:
        log_data = info_holder.LogData.FromFile(args.log_file)
      except files.Error as err:
        log.warning('Error reading the specified file [{0}]: '
                    '{1}\n'.format(args.log_file, err))
    if args.quiet:
      _PrintQuiet(six.text_type(info), log_data)
    else:
      log.status.Print(FEEDBACK_MESSAGE)
      if not log_data:
        log_data = _SuggestIncludeRecentLogs()
      if log_data or console_io.PromptContinue(
          prompt_string=('No invocation selected. Would you still like to file '
                         'a bug (will open a new browser tab)')):
        feedback_util.OpenNewIssueInBrowser(info, log_data)
