# Copyright 2021 The Pigweed Authors
#
# 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
#
#     https://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.
"""Unit tests for pw_software_update.remote_sign module."""

import os
from pathlib import Path
import tempfile
import textwrap
import unittest
from unittest import mock

from google.cloud.storage import Blob  # type: ignore
from google.cloud.storage.bucket import Bucket  # type: ignore

from pw_software_update import remote_sign

# inclusive-language: disable
FAKE_BUILDER_KEY = textwrap.dedent("""\
    -----BEGIN RSA PRIVATE KEY-----
    MIIEpAIBAAKCAQEA4qEQSHM0QpWEhTvhWMBahS7wbTIihaiRpUQC8+hEkmHhoJQy
    zaNR3CKdYWnJ1bAjdBT1HTHznbYSBasFAUKPiB16K/akuKSPnwHG9OM6+8Psw7lt
    GLP2jP65HE4a8n9lGas399xIK4hxZJkV2BXocociXVEVB3nzzNk1AQZdJxik/ToL
    MYC2EKTu1kdt+OLl56/O1Mq9p8V7u2G1l8fqHtJi4Z34LzUzIoyFf7+bSmZBcHG1
    F/QdjbHb4temShDzptOM1VfXZchYTDVnbNsmR7TP2B857agog4rhqtVlPvHqFial
    WEU1WmAQz+oYqtRikUVWHq10SACxo6MFoM7LqQIDAQABAoIBAQCjrdoZyYLUGDLn
    G1FtDTgTesxQwWXnjNDsQMu1J2rnImSX2pE6rhtAV4u9QG9ys01X2I8Tr/EYVdh8
    WYE64LzTfR6ww+lCJjBIkjsEwVznWyEUV0bxEYEfYhWF2O9jdxkoyd2ZWXKSZnAn
    TN1W/LOui+UI6re6d5zatYGvpM4AnlMTmwcO5aPQqTZMBOqJQZgEgyyHH2DZpIRI
    L7dG/k9Y/ML4T+hSVvi84+NS7GyTajPtaNRoVnlwr9+QVKplIgT8ZSqAF7unBsmF
    +s/U+TCFKq0pOhamOVz8eVd/uusy0d7a2oomtKoIzcPd74J5KZMub8izmEOwp5TZ
    17rsBDuVAoGBAPJMv737tYf5T5ihwEJ84OWxq3qLwWSoNwezOF3iWi4r42+QoqsC
    F0dLlgTmsafNTwVP1ztoeGvvezXSUfKfMTjjaZDRB226gwW7+eZ0MbrVcEnI9wm5
    K9MOWut40KsoAHHGs5sLyAtIENwnPAkPQPwPxmEcUxJJZwI/Rq78zR1bAoGBAO9x
    fAi9M8VdbV3r/l1SnExRlTu2gp9Rv02Zy78HVOWEWdEn6mhG3to5mXsHNIQwLulQ
    jm/hBSme5g4xbSCL/qCqRkc1rRautq/W50G8h7S3+KFGdnzXdEYnEh4oh5t5PJtA
    LHWc2WhTe5bsBNwOR1xQ8bEm+V/lf4Fbq+jOcjZLAoGBALzKgDwPfApOf2512c/0
    bWeLYAlEC5PaXcZqJmlAjPOczsGG+Lg2EN1ET8fR2Gre1ctVwmZPqESxfFcbYS6i
    S0AAMajcteURhjVZmgWuU3E4DR3wsEurNDJm5QDEShKSQIZmRFtyepQPutNO3sBQ
    WloMEI5p+3AsMU7W7sQ5xbgxAoGABWwAbwI5xeJTs6jAXcSdHW1Lf8qmMo1bU5qD
    7pNv7LKOhhntSOcx7KcZPpvvKH8e0NGuKAJkZ4jdlLyxx+bjoSe556rjfHwATwMC
    wY5PVFxGGQDLdhA65cvEsUIhr/eS08EkQJWIpsAdMFGv2nvISeLbVjOXugAsXvWA
    cwkZtPkCgYBQJPRCGBz73lBFB16oYJR6AnC32nf0WbrnMLFwMejUrsTLN6M72axw
    bWFpW7rWV7ldSgxKJ6ucKWl78uUMUnkM+CGPt5WJiisZXM2X1Q8+V7fmdAtK/AFj
    /tbEFpftkCyIM1nGZwZ/ziPF4n5hzGGF6w/ZMWZkwFZlqxlejK9IfQ==
    -----END RSA PRIVATE KEY-----
""")

FAKE_BUILDER_PUBLIC_KEY = textwrap.dedent("""\
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4qEQSHM0QpWEhTvhWMBa
    hS7wbTIihaiRpUQC8+hEkmHhoJQyzaNR3CKdYWnJ1bAjdBT1HTHznbYSBasFAUKP
    iB16K/akuKSPnwHG9OM6+8Psw7ltGLP2jP65HE4a8n9lGas399xIK4hxZJkV2BXo
    cociXVEVB3nzzNk1AQZdJxik/ToLMYC2EKTu1kdt+OLl56/O1Mq9p8V7u2G1l8fq
    HtJi4Z34LzUzIoyFf7+bSmZBcHG1F/QdjbHb4temShDzptOM1VfXZchYTDVnbNsm
    R7TP2B857agog4rhqtVlPvHqFialWEU1WmAQz+oYqtRikUVWHq10SACxo6MFoM7L
    qQIDAQAB
    -----END PUBLIC KEY-----
""")

# inclusive-language: enable


# TODO(pwbug/653): Improve unit test coverage.
class PathSigningTest(unittest.TestCase):
    """Tests the signing of bundles by path."""
    @classmethod
    def setUpClass(cls):
        cls.tempdir = tempfile.mkdtemp()

        cls.builder_key = Path(cls.tempdir) / 'fake_builder_key'
        cls.builder_key.write_text(FAKE_BUILDER_KEY)

        cls.builder_pub_key = Path(cls.tempdir) / 'fake_builder_pub_key.pem'
        cls.builder_pub_key.write_text(FAKE_BUILDER_PUBLIC_KEY)

        cls.bundle = Path(cls.tempdir) / 'fake_bundle'
        cls.bundle.write_bytes(b'FAKE BUNDLE CONTENTS\n')

    def test_bundle_blob_uploads(self):
        """Signing should upload the bundle, pub key, and signing request."""
        mock_blob = mock.create_autospec(Blob, instance=True)
        mock_blob.exists = mock.MagicMock(return_value=False)
        mock_in_bucket = mock.create_autospec(Bucket, instance=True)
        mock_in_bucket.blob = mock.MagicMock(return_value=mock_blob)
        mock_out_bucket = mock.create_autospec(Bucket, instance=True)
        mock_out_bucket.name = 'fake_out_bucket'
        client = remote_sign.RemoteSignClient(input_bucket=mock_in_bucket,
                                              output_bucket=mock_out_bucket)

        client.sign(self.bundle,
                    signing_key_name='fake_key',
                    builder_key=self.builder_key,
                    builder_public_key=self.builder_pub_key,
                    request_blob_name='signing_request.json',
                    timeout_s=0.1)

        mock_blob.upload_from_filename.assert_has_calls([
            mock.call(os.path.join(self.tempdir, 'fake_bundle')),
            mock.call(os.path.join(self.tempdir, 'fake_builder_pub_key.pem')),
        ],
                                                        any_order=True)
        mock_blob.upload_from_string.assert_called_once()


if __name__ == '__main__':
    unittest.main()
