# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Package Info (CPV) parsing."""

from __future__ import print_function

import collections
import functools
import re
import string
from typing import Union

# Define data structures for holding PV and CPV objects.
_PV_FIELDS = ['pv', 'package', 'version', 'version_no_rev', 'rev']
PV = collections.namedtuple('PV', _PV_FIELDS)
# See ebuild(5) man page for the field specs these fields are based on.
# Notably, cpv does not include the revision, cpf does.
_CPV_FIELDS = ['category', 'cp', 'cpv', 'cpf'] + _PV_FIELDS
CPV = collections.namedtuple('CPV', _CPV_FIELDS)

# Package matching regexp, as dictated by package manager specification:
# https://www.gentoo.org/proj/en/qa/pms.xml
_pkg = r'(?P<package>' + r'[\w+][\w+-]*)'
_ver = (r'(?P<version>'
        r'(?P<version_no_rev>(\d+)((\.\d+)*)([a-z]?)'
        r'((_(pre|p|beta|alpha|rc)\d*)*))'
        r'(-(?P<rev>r(\d+)))?)')
_pvr_re = re.compile(r'^(?P<pv>%s-%s)$' % (_pkg, _ver), re.VERBOSE)


def _SplitPV(pv, strict=True):
  """Takes a PV value and splits it into individual components.

  Deprecated, use parse() instead.

  Args:
    pv: Package name and version.
    strict: If True, returns None if version or package name is missing.
      Otherwise, only package name is mandatory.

  Returns:
    A collection with named members:
      pv, package, version, version_no_rev, rev
  """
  m = _pvr_re.match(pv)

  if m is None and strict:
    return None

  if m is None:
    return PV(**{'pv': None, 'package': pv, 'version': None,
                 'version_no_rev': None, 'rev': None})

  return PV(**m.groupdict())


def SplitCPV(cpv, strict=True):
  """Splits a CPV value into components.

  Deprecated, use parse() instead.

  Args:
    cpv: Category, package name, and version of a package.
    strict: If True, returns None if any of the components is missing.
      Otherwise, only package name is mandatory.

  Returns:
    A collection with named members:
      category, pv, package, version, version_no_rev, rev
  """
  chunks = cpv.split('/')
  if len(chunks) > 2:
    raise ValueError('Unexpected package format %s' % cpv)
  if len(chunks) == 1:
    category = None
  else:
    category = chunks[0]

  m = _SplitPV(chunks[-1], strict=strict)
  if strict and (category is None or m is None):
    return None

  # Gather parts and build each field. See ebuild(5) man page for spec.
  cp_fields = (category, m.package)
  cp = '%s/%s' % cp_fields if all(cp_fields) else None

  cpv_fields = (cp, m.version_no_rev)
  real_cpv = '%s-%s' % cpv_fields if all(cpv_fields) else None

  cpf_fields = (real_cpv, m.rev)
  cpf = '%s-%s' % cpf_fields if all(cpf_fields) else real_cpv

  return CPV(category=category, cp=cp, cpv=real_cpv, cpf=cpf, **m._asdict())


def parse(cpv: Union[str, CPV, 'PackageInfo']):
  """Parse a package to a PackageInfo object.

  Args:
    cpv: Any package type. This function can parse strings, translate CPVs to a
      PackageInfo instance, and will simply return the argument if given a
      PackageInfo instance.

  Returns:
    PackageInfo
  """
  if isinstance(cpv, PackageInfo):
    return cpv
  elif isinstance(cpv, CPV):
    parsed = cpv
  else:
    parsed = SplitCPV(cpv, strict=False)
  # Temporary measure. SplitCPV parses X-r1 with the revision as r1.
  # Once the SplitCPV function has been fully deprecated we can switch
  # the regex to exclude the r from what it parses as the revision instead.
  # TODO: Change the regex to parse the revision without the r.
  revision = parsed.rev.replace('r', '') if parsed.rev else None
  return PackageInfo(
      category=parsed.category,
      package=parsed.package,
      version=parsed.version_no_rev,
      revision=revision)


class PackageInfo(object):
  """Read-only class to hold and format commonly used package information."""

  def __init__(self, category=None, package=None, version=None, revision=None):
    # Private attributes to enforce read-only. Particularly to allow use of
    # lru_cache for formatting.
    self._category = category
    self._package = package
    self._version = version
    self._revision = int(revision) if revision else 0

  def __eq__(self, other):
    try:
      return (self.category == other.category and
              self.package == other.package and
              str(self.version) == str(other.version) and
              str(self.revision) == str(other.revision))
    except AttributeError:
      return False

  def __hash__(self):
    return hash((self._category, self._package, self._version, self._revision))

  @functools.lru_cache()
  def __format__(self, format_spec):
    """Formatter function.

    The format |spec| is a format string containing any combination of:
    {c}, {p}, {v}, or {r} for the package's category, package name, version,
    or revision, respectively, or any of the class' {attribute}s.
    e.g. {c}/{p} or {atom} for a package's atom (i.e. category/package_name).
    """
    fmtter = string.Formatter()
    base_dict = {
        'c': self.category,
        'p': self.package,
        'v': self.version,
        # Force 'r' to be None when we have 0 to avoid -r0 suffixes.
        'r': self.revision or None,
    }
    fields = (x for _, x, _, _ in fmtter.parse(format_spec) if x)
    # Setting base_dict.get(x) as the default value for getattr allows it to
    # fall back to valid, falsey values in the base_dict rather than
    # overwriting them with None, i.e. 0 for version or revision.
    fmt_dict = {x: getattr(self, x, base_dict.get(x)) for x in fields}

    # We can almost do `if all(fmt_dict.values()):` to just check for falsey
    # values here, but 0 is a valid version value.
    if any(v in ('', None) for v in fmt_dict.values()):
      return ''

    return format_spec.format(**fmt_dict)

  @property
  def category(self):
    return self._category

  @property
  def package(self):
    return self._package

  @property
  def version(self):
    return self._version

  @property
  def revision(self):
    return self._revision

  @property
  def cpv(self):
    return format(self, '{c}/{p}-{v}')

  @property
  def cpvr(self):
    return format(self, '{cpv}-r{r}') or self.cpv

  @property
  def cpf(self):
    """CPF is the portage name for cpvr, provided to simplify transition."""
    return self.cpvr

  @property
  def atom(self):
    return format(self, '{c}/{p}')

  @property
  def cp(self):
    return self.atom

  @property
  def pv(self):
    return format(self, '{p}-{v}')

  @property
  def pvr(self):
    return format(self, '{pv}-r{r}') or self.pv

  @property
  def vr(self):
    return format(self, '{v}-r{r}') or self.version

  @property
  def ebuild(self):
    return format(self, '{pvr}.ebuild')

  @property
  def relative_path(self):
    """Path of the ebuild relative to its overlay."""
    return format(self, '{c}/{p}/{ebuild}')

  def revision_bump(self):
    """Get a PackageInfo instance with an incremented revision."""
    return PackageInfo(self.category, self.package, self.version,
                       self.revision + 1)

  def with_version(self, version):
    """Get a PackageInfo instance with the new, specified version."""
    return PackageInfo(self.category, self.package, version)
