# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""FLT task to be manually triggered to convert launch issues."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import collections
import logging
import re
import settings
import time

from businesslogic import work_env
from framework import permissions
from framework import exceptions
from framework import jsonfeed
from proto import tracker_pb2
from tracker import template_helpers
from tracker import tracker_bizobj

PM_PREFIX = 'pm-'
TL_PREFIX = 'tl-'
TEST_PREFIX = 'test-'
UX_PREFIX = 'ux-'

PM_FIELD = 'pm'
TL_FIELD = 'tl'
TE_FIELD = 'te'
UX_FIELD = 'ux'
MTARGET_FIELD = 'm-target'
MAPPROVED_FIELD = 'm-approved'

CONVERSION_COMMENT = 'Automatic generating of FLT Launch data.'

BROWSER_APPROVALS_TO_LABELS = {
    'Chrome-Accessibility': 'Launch-Accessibility-',
    'Chrome-Leadership-Exp': 'Launch-Exp-Leadership-',
    'Chrome-Leadership-Full': 'Launch-Leadership-',
    'Chrome-Legal': 'Launch-Legal-',
    'Chrome-Privacy': 'Launch-Privacy-',
    'Chrome-Security': 'Launch-Security-',
    'Chrome-Test': 'Launch-Test-',
    'Chrome-UX': 'Launch-UI-',
    }

OS_APPROVALS_TO_LABELS = {
    'ChromeOS-Accessibility': 'Launch-Accessibility-',
    'ChromeOS-Leadership-Exp': 'Launch-Exp-Leadership-',
    'ChromeOS-Leadership-Full': 'Launch-Leadership-',
    'ChromeOS-Legal': 'Launch-Legal-',
    'ChromeOS-Privacy': 'Launch-Privacy-',
    'ChromeOS-Security': 'Launch-Security-',
    'ChromeOS-Test': 'Launch-Test-',
    'ChromeOS-UX': 'Launch-UI-',
    }

# 'NotReviewed' not included because this should be converted to
# the template approval's default value, eg NOT_SET OR NEEDS_REVIEW
VALUE_TO_STATUS = {
    'ReviewRequested': tracker_pb2.ApprovalStatus.REVIEW_REQUESTED,
    'NeedInfo': tracker_pb2.ApprovalStatus.NEED_INFO,
    'Yes': tracker_pb2.ApprovalStatus.APPROVED,
    'No': tracker_pb2.ApprovalStatus.NOT_APPROVED,
    'NA': tracker_pb2.ApprovalStatus.NA,
    # 'Started' is not a valid label value in the chromium project,
    # but for some reason, some labels have this value.
    'Started': tracker_pb2.ApprovalStatus.REVIEW_STARTED,
}

# This works in the Browser and OS process because
# BROWSER_APPROVALS_TO_LABELS and OS_APPROVALS_TO_LABELS have the same values.
# Adding '^' before each label prefix to ensure Blah-Launch-UI-Yes is ignored
REVIEW_LABELS_RE = re.compile('^' + '|^'.join(
    list(OS_APPROVALS_TO_LABELS.values())))

# Maps template phases to channel names in 'Launch-M-Target-80-[Channel]' labels
BROWSER_PHASE_MAP = {
    'beta': 'beta',
    'stable': 'stable',
    'stable-full': 'stable',
    'stable-exp': 'stable-exp',
    }

PHASE_PAT = '$|'.join(list(BROWSER_PHASE_MAP.values()))
# Matches launch milestone labels, eg. Launch-M-Target-70-Stable-Exp
BROWSER_M_LABELS_RE = re.compile(
    r'^Launch-M-(?P<type>Approved|Target)-(?P<m>\d\d)-'
    r'(?P<channel>%s$)' % PHASE_PAT,
    re.IGNORECASE)

OS_PHASE_MAP = {'feature freeze': '',
                 'branch': '',
                'stable': 'stable',
                'stable-full': 'stable',
                'stable-exp': 'stable-exp',}
# We only care about Launch-M-<type>-<m>-Stable|Stable-Exp labels for OS.
OS_M_LABELS_RE = re.compile(
    r'^Launch-M-(?P<type>Approved|Target)-(?P<m>\d\d)-'
    r'(?P<channel>Stable$|Stable-Exp$)', re.IGNORECASE)

CAN = 2  # Query for open issues only
# Ensure empty group_by_spec and sort_spec so issues are sorted by 'ID'.
GROUP_BY_SPEC = ''
SORT_SPEC = ''

CONVERT_NUM = 20
CONVERT_START = 0
VERIFY_NUM = 400

# Queries
QUERY_MAP = {
    'default':
    'Type=Launch Rollout-Type=Default OS=Windows,Mac,Linux,Android,iOS',
    'finch': 'Type=Launch Rollout-Type=Finch OS=Windows,Mac,Linux,Android,iOS',
    'os': 'Type=Launch OS=Chrome -OS=Windows,Mac,Linux,Android,iOS'
    ' Rollout-Type=Default',
    'os-finch': 'Type=Launch OS=Chrome -OS=Windows,Mac,Linux,Android,iOS'
    ' Rollout-Type=Finch'}

TEMPLATE_MAP = {
    'default': 'Chrome Launch - Default',
    'finch': 'Chrome Launch - Experimental',
    'os': 'Chrome OS Launch - Default',
    'os-finch': 'Chrome OS Launch - Experimental',
}

ProjectInfo = collections.namedtuple(
    'ProjectInfo', 'config, q, approval_values, phases, '
    'pm_fid, tl_fid, te_fid, ux_fid, m_target_id, m_approved_id, '
    'phase_map, approvals_to_labels, labels_re')


# TODO: change to FlaskInternalTask when convert to flask
class FLTConvertTask(jsonfeed.InternalTask):
  """FLTConvert converts current Type=Launch issues into Type=FLT-Launch."""

  def AssertBasePermission(self, mr):
    super(FLTConvertTask, self).AssertBasePermission(mr)
    if not mr.auth.user_pb.is_site_admin:
      raise permissions.PermissionException(
          'Only site admins may trigger conversion job')

  def UndoConversion(self, mr):
    with work_env.WorkEnv(mr, self.services) as we:
      pipeline = we.ListIssues(
          'Type=FLT-Launch FLT=Conversion', ['chromium'], mr.auth.user_id,
          CONVERT_NUM, CONVERT_START, 2, GROUP_BY_SPEC, SORT_SPEC, False)

    project = self.services.project.GetProjectByName(mr.cnxn, 'chromium')
    config = self.services.config.GetProjectConfig(mr.cnxn, project.project_id)
    pm_id = tracker_bizobj.FindFieldDef('PM', config).field_id
    tl_id = tracker_bizobj.FindFieldDef('TL', config).field_id
    te_id = tracker_bizobj.FindFieldDef('TE', config).field_id
    ux_id = tracker_bizobj.FindFieldDef('UX', config).field_id
    for possible_stale_issue in pipeline.visible_results:
      issue = self.services.issue.GetIssue(
          mr.cnxn, possible_stale_issue.issue_id, use_cache=False)

      issue.approval_values = []
      issue.phases = []
      issue.field_values = [fv for fv in issue.field_values
                            if fv.phase_id is None]
      issue.field_values = [fv for fv in issue.field_values
                            if fv.field_id not in
                            [pm_id, tl_id, te_id, ux_id]]
      issue.labels.remove('Type-FLT-Launch')
      issue.labels.remove('FLT-Conversion')
      issue.labels.append('Type-Launch')

      self.services.issue._UpdateIssuesApprovals(mr.cnxn, issue)
      self.services.issue.UpdateIssue(mr.cnxn, issue)
    return {'deleting': [issue.local_id for issue in pipeline.visible_results],
            'num': len(pipeline.visible_results),
    }

  def VerifyConversion(self, mr):
    """Verify that all FLT-Conversion issues were converted correctly."""
    with work_env.WorkEnv(mr, self.services) as we:
      pipeline = we.ListIssues(
          'FLT=Conversion', ['chromium'], mr.auth.user_id, VERIFY_NUM,
          CONVERT_START, 2, GROUP_BY_SPEC, SORT_SPEC, False)

    project = self.services.project.GetProjectByName(mr.cnxn, 'chromium')
    config = self.services.config.GetProjectConfig(mr.cnxn, project.project_id)
    browser_approval_names = {fd.field_id: fd.field_name for fd
                              in config.field_defs if fd.field_name in
                              BROWSER_APPROVALS_TO_LABELS.keys()}
    os_approval_names = {fd.field_id: fd.field_name for fd in config.field_defs
                         if (fd.field_name in OS_APPROVALS_TO_LABELS.keys())
                         or fd.field_name == 'ChromeOS-Enterprise'}
    pm_id = tracker_bizobj.FindFieldDef('PM', config).field_id
    tl_id = tracker_bizobj.FindFieldDef('TL', config).field_id
    te_id = tracker_bizobj.FindFieldDef('TE', config).field_id
    ux_id = tracker_bizobj.FindFieldDef('UX', config).field_id
    mapproved_id = tracker_bizobj.FindFieldDef('M-Approved', config).field_id
    mtarget_id = tracker_bizobj.FindFieldDef('M-Target', config).field_id

    problems = []
    for possible_stale_issue in pipeline.allowed_results:
      issue = self.services.issue.GetIssue(
          mr.cnxn, possible_stale_issue.issue_id, use_cache=False)
      # Check correct template used
      approval_names = browser_approval_names
      approvals_to_labels = BROWSER_APPROVALS_TO_LABELS
      m_labels_re = BROWSER_M_LABELS_RE
      label_channel_to_phase_id = {
          phase.name.lower(): phase.phase_id for phase in issue.phases}
      if [l for l in issue.labels if l.startswith('OS-')] == ['OS-Chrome']:
        approval_names = os_approval_names
        m_labels_re = OS_M_LABELS_RE
        approvals_to_labels = OS_APPROVALS_TO_LABELS
        # OS default launch
        if 'Rollout-Type-Default' in issue.labels:
          if not all(phase.name in ['Feature Freeze', 'Branch', 'Stable']
                     for phase in issue.phases):
            problems.append((
                issue.local_id, 'incorrect phases for OS default launch.'))
        # OS finch launch
        elif 'Rollout-Type-Finch' in issue.labels:
          if not all(phase.name in (
              'Feature Freeze', 'Branch', 'Stable-Exp', 'Stable-Full')
                     for phase in issue.phases):
            problems.append((
                issue.local_id, 'incorrect phases for OS finch launch.'))
        else:
          problems.append((
              issue.local_id,
              'no rollout-type; should not have been converted'))
      # Browser default launch
      elif 'Rollout-Type-Default' in issue.labels:
        if not all(phase.name.lower() in ['beta', 'stable']
                   for phase in issue.phases):
          problems.append((
              issue.local_id, 'incorrect phases for Default rollout'))
      # Browser finch launch
      elif 'Rollout-Type-Finch' in issue.labels:
        if not all(phase.name.lower() in ['beta', 'stable-exp', 'stable-full']
                   for phase in issue.phases):
          problems.append((
              issue.local_id, 'incorrect phases for Finch rollout'))
      else:
        problems.append((
            issue.local_id,
            'no rollout-type; should not have been converted'))

      # Check approval_values
      for av in issue.approval_values:
        name = approval_names.get(av.approval_id)
        if name == 'ChromeOS-Enterprise':
          if av.status != tracker_pb2.ApprovalStatus.NEEDS_REVIEW:
            problems.append((issue.local_id, 'bad ChromeOS-Enterprise status'))
          continue
        label_pre = approvals_to_labels.get(name)
        if not label_pre:
          # either name was None or not found in APPROVALS_TO_LABELS
          problems.append((issue.local_id, 'approval %s not recognized' % name))
          continue
        label_value = next((l[len(label_pre):] for l in issue.labels
                            if l.startswith(label_pre)), None)
        if (not label_value or label_value == 'NotReviewed') and av.status in [
            tracker_pb2.ApprovalStatus.NOT_SET,
            tracker_pb2.ApprovalStatus.NEEDS_REVIEW]:
          continue
        if av.status is VALUE_TO_STATUS.get(label_value):
          continue
        # neither of the above ifs passed
        problems.append((issue.local_id,
                         'approval %s has status %r for label value %s' % (
                             name, av.status.name, label_value)))

      # Check people field_values
      expected_people_fvs = self.ConvertPeopleLabels(
          mr, issue.labels, pm_id, tl_id, te_id, ux_id)
      for people_fv in expected_people_fvs:
        if people_fv not in issue.field_values:
          if people_fv.field_id == tl_id:
            role = 'TL'
          elif people_fv.field_id == pm_id:
            role = 'PM'
          elif people_fv.field_id == ux_id:
            role = 'UX'
          else:
            role = 'TE'
          problems.append((issue.local_id, 'missing a field for %s' % role))

      # Check M phase field_values
      for label in issue.labels:
        match = re.match(m_labels_re, label)
        if match:
          channel = match.group('channel')
          if (channel.lower() == 'stable-exp'
              and 'Rollout-Type-Default' in issue.labels):
            # ignore stable-exp for default rollouts.
            continue
          milestone = match.group('m')
          m_type = match.group('type')
          m_id = mapproved_id if m_type == 'Approved' else mtarget_id
          phase_id = label_channel_to_phase_id.get(
              channel.lower(), label_channel_to_phase_id.get('stable-full'))
          if not next((
              fv for fv in issue.field_values
              if fv.phase_id == phase_id and fv.field_id == m_id and
              fv.int_value == int(milestone)), None):
            problems.append((
                issue.local_id, 'no phase field for label %s' % label))

    return {
        'problems found': ['issue %d: %s' % problem for problem in problems],
        'issues verified': ['issue %d' % issue.local_id for
                            issue in pipeline.allowed_results],
        'num': len(pipeline.allowed_results),
    }

  def HandleRequest(self, mr):
    """Convert Type=Launch issues to new Type=FLT-Launch issues."""
    launch = mr.GetParam('launch')
    if launch == 'delete':
      return self.UndoConversion(mr)
    if launch == 'verify':
      return self.VerifyConversion(mr)
    project_info = self.FetchAndAssertProjectInfo(mr)

    # Search for issues:
    with work_env.WorkEnv(mr, self.services) as we:
      pipeline = we.ListIssues(
          project_info.q, ['chromium'], mr.auth.user_id, CONVERT_NUM,
          CONVERT_START, 2, GROUP_BY_SPEC, SORT_SPEC, False)

    # Convert issues:
    for possible_stale_issue in pipeline.visible_results:
      # Note: These approval values and phases from templates will be used
      # and modified to create approval values and phases for each issue.
      # We need to create copies for each issue so changes are not carried
      # over to the conversion of the next issue in the loop.
      template_avs = self.CreateApprovalCopies(project_info.approval_values)
      template_phases = self.CreatePhasesCopies(project_info.phases)
      issue = self.services.issue.GetIssue(
          mr.cnxn, possible_stale_issue.issue_id, use_cache=False)
      new_approvals = ConvertLaunchLabels(
          issue.labels, template_avs,
          project_info.config.field_defs, project_info.approvals_to_labels)
      m_fvs = ConvertMLabels(
          issue.labels, template_phases,
          project_info.m_target_id, project_info.m_approved_id,
          project_info.labels_re, project_info.phase_map)
      people_fvs = self.ConvertPeopleLabels(
          mr, issue.labels,
          project_info.pm_fid, project_info.tl_fid, project_info.te_fid,
          project_info.ux_fid)
      amendments = self.ExecuteIssueChanges(
          project_info.config, issue, new_approvals,
          template_phases, m_fvs + people_fvs)
      logging.info(amendments)

    return {
        'converted_issues': [
            issue.local_id for issue in pipeline.visible_results],
        'num': len(pipeline.visible_results),
        }

  def CreateApprovalCopies(self, avs):
    return [
      tracker_pb2.ApprovalValue(
          approval_id=av.approval_id,
          status=av.status,
          setter_id=av.setter_id,
          set_on=av.set_on,
          phase_id=av.phase_id) for av in avs
    ]

  def CreatePhasesCopies(self, phases):
    return [
      tracker_pb2.Phase(
          phase_id=phase.phase_id,
          name=phase.name,
          rank=phase.rank) for phase in phases
        ]

  def FetchAndAssertProjectInfo(self, mr):
    # Get request details
    launch = mr.GetParam('launch')
    logging.info(launch)
    q = QUERY_MAP.get(launch)
    template_name = TEMPLATE_MAP.get(launch)
    assert q and template_name, 'bad launch type: %s' % launch

    phase_map = (
        OS_PHASE_MAP if launch in ['os', 'os-finch'] else BROWSER_PHASE_MAP)
    approvals_to_labels = (
        OS_APPROVALS_TO_LABELS if launch in ['os', 'os-finch']
        else BROWSER_APPROVALS_TO_LABELS)
    m_labels_re = (
        OS_M_LABELS_RE if launch in ['os', 'os-finch'] else BROWSER_M_LABELS_RE)

    # Get project, config, template, assert template in project
    project = self.services.project.GetProjectByName(mr.cnxn, 'chromium')
    config = self.services.config.GetProjectConfig(mr.cnxn, project.project_id)
    template = self.services.template.GetTemplateByName(
        mr.cnxn, template_name, project.project_id)
    assert template, 'template %s not found in chromium project' % template_name

    # Get template approval_values/phases and assert they are expected
    approval_values, phases = template_helpers.FilterApprovalsAndPhases(
        template.approval_values, template.phases, config)
    assert approval_values and phases, (
        'no approvals or phases in %s' % template_name)
    assert all(phase.name.lower() in list(
        phase_map.keys()) for phase in phases), (
          'one or more phases not recognized')
    if launch in ['finch', 'os', 'os-finch']:
      assert all(
          av.status is tracker_pb2.ApprovalStatus.NEEDS_REVIEW
          for av in approval_values
      ), '%s template not set up correctly' % launch

    approval_fds = {fd.field_id: fd.field_name for fd in config.field_defs
                    if fd.field_type is tracker_pb2.FieldTypes.APPROVAL_TYPE}
    assert all(
        approval_fds.get(av.approval_id) in list(approvals_to_labels.keys())
        for av in approval_values
        if approval_fds.get(av.approval_id) != 'ChromeOS-Enterprise'), (
            'one or more approvals not recognized')
    approval_def_ids = [ad.approval_id for ad in config.approval_defs]
    assert all(av.approval_id in approval_def_ids for av in approval_values), (
        'one or more approvals not in config.approval_defs')

    # Get relevant USER_TYPE FieldDef ids and assert they exist
    user_fds = {fd.field_name.lower(): fd.field_id for fd in config.field_defs
                    if fd.field_type is tracker_pb2.FieldTypes.USER_TYPE}
    logging.info('project USER_TYPE FieldDefs: %s' % user_fds)
    pm_fid = user_fds.get(PM_FIELD)
    assert pm_fid, 'project has no FieldDef %s' % PM_FIELD
    tl_fid = user_fds.get(TL_FIELD)
    assert tl_fid, 'project has no FieldDef %s' % TL_FIELD
    te_fid = user_fds.get(TE_FIELD)
    assert te_fid, 'project has no FieldDef %s' % TE_FIELD
    ux_fid = user_fds.get(UX_FIELD)
    assert ux_fid, 'project has no FieldDef %s' % UX_FIELD

    # Get relevant M Phase INT_TYPE FieldDef ids and assert they exist
    phase_int_fds = {fd.field_name.lower(): fd.field_id
                     for fd in config.field_defs
                     if fd.field_type is tracker_pb2.FieldTypes.INT_TYPE
                     and fd.is_phase_field and fd.is_multivalued}
    logging.info(
        'project Phase INT_TYPE multivalued FieldDefs: %s' % phase_int_fds)
    m_target_id = phase_int_fds.get(MTARGET_FIELD)
    assert m_target_id, 'project has no FieldDef %s' % MTARGET_FIELD
    m_approved_id = phase_int_fds.get(MAPPROVED_FIELD)
    assert m_approved_id, 'project has no FieldDef %s' % MAPPROVED_FIELD

    return ProjectInfo(config, q, approval_values, phases, pm_fid, tl_fid,
                       te_fid, ux_fid, m_target_id, m_approved_id, phase_map,
                       approvals_to_labels, m_labels_re)

  # TODO(jojwang): mr needs to be passed in as arg and
  # all self.mr should be changed to mr
  def ExecuteIssueChanges(self, config, issue, new_approvals, phases, new_fvs):
    # Apply Approval and phase changes
    approval_defs_by_id = {ad.approval_id: ad for ad in config.approval_defs}
    for av in new_approvals:
      ad = approval_defs_by_id.get(av.approval_id)
      if ad:
        av.approver_ids = ad.approver_ids
        survey = ''
        if ad.survey:
          questions = ad.survey.split('\n')
          survey = '\n'.join(['<b>' + q + '</b>' for q in questions])
        self.services.issue.InsertComment(
            self.mr.cnxn, tracker_pb2.IssueComment(
                issue_id=issue.issue_id, project_id=issue.project_id,
                user_id=self.mr.auth.user_id, content=survey,
                is_description=True, approval_id=av.approval_id,
                timestamp=int(time.time())))
      else:
        logging.info(
            'ERROR: ApprovalDef %r for ApprovalValue %r not valid', ad, av)
    issue.approval_values = new_approvals
    self.services.issue._UpdateIssuesApprovals(self.mr.cnxn, issue)

    # Apply field value changes
    issue.phases = phases
    delta = tracker_bizobj.MakeIssueDelta(
        None, None, [], [], [], [], ['Type-FLT-Launch', 'FLT-Conversion'],
        ['Type-Launch'], new_fvs, [], [], [], [], [], [], None, None)
    amendments, _ = self.services.issue.DeltaUpdateIssue(
        self.mr.cnxn, self.services, self.mr.auth.user_id, issue.project_id,
        config, issue, delta, comment=CONVERSION_COMMENT)

    return amendments

  def ConvertPeopleLabels(
      self, mr, labels, pm_field_id, tl_field_id, te_field_id, ux_field_id):
    field_values = []
    pm_ldap, tl_ldap, test_ldaps, ux_ldaps = ExtractLabelLDAPs(labels)

    pm_fv = self.CreateUserFieldValue(mr, pm_ldap, pm_field_id)
    if pm_fv:
      field_values.append(pm_fv)

    tl_fv = self.CreateUserFieldValue(mr, tl_ldap, tl_field_id)
    if tl_fv:
      field_values.append(tl_fv)

    for test_ldap in test_ldaps:
      te_fv = self.CreateUserFieldValue(mr, test_ldap, te_field_id)
      if te_fv:
        field_values.append(te_fv)

    for ux_ldap in ux_ldaps:
      ux_fv = self.CreateUserFieldValue(mr, ux_ldap, ux_field_id)
      if ux_fv:
        field_values.append(ux_fv)
    return field_values

  def CreateUserFieldValue(self, mr, ldap, field_id):
    if ldap is None:
      return None
    try:
      user_id = self.services.user.LookupUserID(mr.cnxn, ldap+'@chromium.org')
    except exceptions.NoSuchUserException:
      try:
        user_id = self.services.user.LookupUserID(mr.cnxn, ldap+'@google.com')
      except exceptions.NoSuchUserException:
        logging.info('No chromium.org or google.com accound found for %s', ldap)
        return None
    return tracker_bizobj.MakeFieldValue(
        field_id, None, None, user_id, None, None, False)

  # def GetFLTConvertTask(self, **kwargs):
  #   return self.handler(**kwargs)

  # def PostFLTConvertTask(self, **kwargs):
  #   return self.handler(**kwargs)


def ConvertMLabels(
    labels, phases, m_target_id, m_approved_id, labels_re, phase_map):
  field_values = []
  for label in labels:
    match = re.match(labels_re, label)
    if match:
      milestone = match.group('m')
      m_type = match.group('type')
      channel = match.group('channel')
      for phase in phases:
        # We know get(phase) will return something because
        # we're checking before ConvertMLabels, that all phases
        # exist in BROWSER_PHASE_MAP or OS_PHASE_MAP
        if phase_map.get(phase.name.lower()) == channel.lower():
          field_id = m_target_id if (
              m_type.lower() == 'target') else m_approved_id
          field_values.append(tracker_bizobj.MakeFieldValue(
              field_id, int(milestone), None, None, None, None, False,
              phase_id=phase.phase_id))
          break  # exit phase loop if match is found.
  return field_values


def ConvertLaunchLabels(labels, approvals, project_fds, approvals_to_labels):
  """Converts 'Launch-[Review]' values into statuses for given approvals."""
  label_values = {}
  for label in labels:
    launch_match = REVIEW_LABELS_RE.match(label)
    if launch_match:
      prefix = launch_match.group()
      value = label[len(prefix):]  # returns 'Yes' from 'Launch-UI-Yes'
      label_values[prefix] = value

  field_names_dict = {fd.field_id: fd.field_name for fd in project_fds}
  for approval in approvals:
    approval_name = field_names_dict.get(approval.approval_id, '')
    old_prefix = approvals_to_labels.get(approval_name)
    label_value = label_values.get(old_prefix, '')
    # if label_value not found in VALUE_TO_STATUS, use current status.
    approval.status = VALUE_TO_STATUS.get(label_value, approval.status)

  return approvals


def ExtractLabelLDAPs(labels):
  """Extracts LDAPs from labels 'PM-', 'TL-', 'UX-', and 'test-'"""

  pm_ldap = None
  tl_ldap = None
  test_ldaps = []
  ux_ldaps = []
  for label in labels:
    label = label.lower()
    if label.startswith(PM_PREFIX):
      pm_ldap = label[len(PM_PREFIX):]
    elif label.startswith(TL_PREFIX):
      tl_ldap = label[len(TL_PREFIX):]
    elif label.startswith(TEST_PREFIX):
      ldap = label[len(TEST_PREFIX):]
      if ldap:
        test_ldaps.append(ldap)
    elif label.startswith(UX_PREFIX):
      ldap = label[len(UX_PREFIX):]
      if ldap:
        ux_ldaps.append(ldap)
  return pm_ldap, tl_ldap, test_ldaps, ux_ldaps
