# Copyright (C) 2018 Sony Interactive Entertainment Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


import re


def load(filesystem, path):
    """Load PEM file and return PEM object"""
    return Pem(filesystem.read_text_file(path))


class BadFormatError(Exception):
    """Bad format error"""
    pass


class Pem(object):
    """
    Container for certificate related information.
    Each section in PEM file can be accessible by get().
    e.g.
    pem = pemfile.load(filesystem, "/path/to/sample.pem")
    assert pem.certificate.startswith("-----BEGIN CERTIFICATE-----")
    """

    def __init__(self, content):
        self._contents = _parse_pem_format(content)
        if not self._contents:
            raise BadFormatError("Cannot find any sections in this file.")

    def get(self, kind):
        """Return requested information or None if not found."""
        items = self.get_all(kind)
        if not items:
            raise KeyError("{} is not in this PEM".format(kind))
        return items[0]

    def get_all(self, kind):
        """Return all matching requested information"""
        return [content for (key, content) in self._contents if key == kind]

    @property
    def certificate(self):
        """Return certificate"""
        return self.get(CERTIFICATE)

    @property
    def private_key(self):
        """Return private key"""
        return self.get(PRIVATE_KEY)

    @property
    def csr(self):
        """Return certificate request"""
        return self.get(CERTIFICATE_REQUEST)

    @property
    def certificate_request(self):
        """Alias for csr()"""
        return self.csr

    @property
    def certificate_signing_request(self):
        """Alias for csr()"""
        return self.csr


MARKER = "-----"
BEGIN_MARKER = "BEGIN "
END_MARKER = "END"

CERTIFICATE_REQUEST = "CERTIFICATE REQUEST"
PRIVATE_KEY = "PRIVATE KEY"
CERTIFICATE = "CERTIFICATE"

BEGIN_PATTERN = re.compile("^{}BEGIN (.+){}$".format(MARKER, MARKER))


def _parse_pem_format(content):
    lines = re.split('\r\n?|\n', content)

    def find_begin(lines):
        """
        Find first matching BEGIN marker.
        @returns found key and rest of lines | None
        """
        while lines:
            matched = BEGIN_PATTERN.match(lines[0])
            if matched:
                return (matched.group(1), lines)
            lines = lines[1:]
        return None

    def find_end(kind, lines):
        """
        Find END marker.
        @returns key, found contents and rest of lines.
        @raise BadFormatError
        """
        end_marker = "{}END {}{}".format(MARKER, kind, MARKER)

        try:
            index = lines.index(end_marker)
        except ValueError:
            raise BadFormatError("Cannot find section end: {}".format(end_marker))

        return kind, "\n".join(lines[0:index + 1]) + "\n", lines[index + 1:]

    def sections(lines):
        """Section Generator"""
        while lines:
            result = find_begin(lines)
            if not result:
                break
            key, body, lines = find_end(*result)
            yield (key, body)

    return [section for section in sections(lines)]
