# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Redirect Middleware for Monorail.

Handles traffic redirection before hitting main monorail app.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import flask
from redirect import redirect_utils
from redirect import redirectissue


class RedirectMiddleware(object):

  def __init__(self, main_app, redirect_app):
    self._main_app = main_app
    self._redirect_app = redirect_app

  def __call__(self, environ, start_response):
    # Run the redirect app first.
    response = flask.Response.from_app(self._redirect_app, environ)
    if response.status_code == 404:
      # If it returns 404, run the main app.
      return self._main_app(environ, start_response)
    # Otherwise, return the response from the redirect app.
    app_iter, status, headers = response.get_wsgi_response(environ)
    start_response(status, headers)
    return app_iter


def GenerateRedirectApp():
  redirect_app = flask.Flask(__name__)

  def PreCheckHandler():
    # Should not redirect away from monorail if param set.
    r = flask.request
    no_redirect = 'no_tracker_redirect' in r.args
    if no_redirect:
      flask.abort(404)
  redirect_app.before_request(PreCheckHandler)

  def IssueList(project_name):
    redirect_url = redirect_utils.GetRedirectURL(project_name)
    if redirect_url:
      query_string = redirect_utils.GetSearchQuery(
          project_name, flask.request.args)
      return flask.redirect(redirect_url + '/issues?' + query_string)
    flask.abort(404)

  redirect_app.route('/p/<string:project_name>/')(IssueList)
  redirect_app.route('/p/<string:project_name>/issues/')(IssueList)
  redirect_app.route('/p/<string:project_name>/issues/list')(IssueList)
  redirect_app.route('/p/<string:project_name>/issues/list_new')(IssueList)

  def IssueDetail(project_name):
    local_id = flask.request.args.get('id', type=int)
    if not local_id:
      flask.abort(404)

    redirect_url = _GenerateIssueDetailRedirectURL(local_id, project_name)
    if redirect_url:
      return flask.render_template('redirect.html', base_url=redirect_url)
    flask.abort(404)
  redirect_app.route('/p/<string:project_name>/issues/detail')(IssueDetail)

  def IssueCreate(project_name):
    redirect_url = redirect_utils.GetRedirectURL(project_name)
    if redirect_url:
      query_string = redirect_utils.GetNewIssueParams(
          flask.request.args, project_name)
      return flask.redirect(redirect_url + '/new?' + query_string)
    flask.abort(404)
  redirect_app.route('/p/<string:project_name>/issues/entry')(IssueCreate)
  redirect_app.route('/p/<string:project_name>/issues/entry_new')(IssueCreate)

  return redirect_app


def _GenerateIssueDetailRedirectURL(local_id, project_name):
  redirect_base_url = redirect_utils.GetRedirectURL(project_name)
  if not redirect_base_url:
    return None

  if local_id > redirect_utils.MAX_MONORAIL_ISSUE_ID:
    return redirect_base_url + '/' + str(local_id)

  tracker_id = redirectissue.RedirectIssue.Get(project_name, local_id)
  if tracker_id:
    return redirect_base_url + '/' + tracker_id
  return None
