# --
# Copyright (C) 2001-2021 OTRS AG, https://otrs.com/
# Copyright (C) 2021 Znuny GmbH, https://znuny.org/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --

use strict;
use warnings;
use utf8;

use vars (qw($Self));

local $ENV{SCRIPT_NAME} = 'index.pl';

my $HelperObject = $Kernel::OM->Get('Kernel::System::UnitTest::Helper');

$Kernel::OM->ObjectParamAdd(
    'Kernel::Output::HTML::Layout' => {
        Lang      => 'de',
        SessionID => 123,
    },
);
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');

# Disable global external content blocking.
$HelperObject->ConfigSettingChange(
    Valid => 1,
    Key   => 'Ticket::Frontend::BlockLoadingRemoteContent',
    Value => 0,
);

my @Tests = (
    {
        Name => 'Content img',
        Data => {
            Content     => '<img src="cid:1234567890ABCDEF">',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<1234567890ABCDEF>',
            },
        },
        Result => {
            ContentType => 'text/html; charset="utf-8"',
            Content     => '<img src="index.pl?Action=SomeAction;FileID=0;SessionID=123">',
        },
    },
    {
        Name => 'Content img with inline style',
        Data => {
            Content     => "<img border=\"0\" src=\"cid:1234567890ABCDEF\">",
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<1234567890ABCDEF>',
            },
        },
        Result => {
            Content =>
                '<img border="0" src="index.pl?Action=SomeAction;FileID=0;SessionID=123">',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Content img with inline style and line breaks',
        Data => {
            Content     => "<img border=\"0\" \nsrc=\"cid:1234567890ABCDEF\">",
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<1234567890ABCDEF>',
            },
        },
        Result => {
            Content =>
                "<img border=\"0\" \nsrc=\"index.pl?Action=SomeAction;FileID=0;SessionID=123\">",
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Content img',
        Data => {
            Content     => '<img src=cid:1234567890ABCDEF>',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<1234567890ABCDEF>',
            },
        },
        Result => {
            Content =>
                '<img src="index.pl?Action=SomeAction;FileID=0;SessionID=123">',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Content img with break',
        Data => {
            Content     => '<img src=cid:1234567890ABCDEF />',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<1234567890ABCDEF>',
            },
        },
        Result => {
            Content =>
                '<img src="index.pl?Action=SomeAction;FileID=0;SessionID=123" />',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Content img with single quotes',
        Data => {
            Content     => '<img src=\'cid:1234567890ABCDEF\' />',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<1234567890ABCDEF>',
            },
        },
        Result => {
            Content =>
                '<img src=\'index.pl?Action=SomeAction;FileID=0;SessionID=123\' />',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Content img with single quotes and break',
        Data => {
            Content     => '<img src=\'Untitled%20Attachment\' />',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<Untitled%20Attachment>',
            },
        },
        Result => {
            Content =>
                '<img src=\'index.pl?Action=SomeAction;FileID=0;SessionID=123\' />',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'drop script tag',
        Data => {
            Content     => '1<script></script>',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<Untitled%20Attachment>',
            },
        },
        Result => {
            Content     => '1',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'keep script tag',
        Data => {
            Content     => '1<script></script>',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<Untitled%20Attachment>',
            },
        },
        LoadInlineContent => 1,
        Result            => {
            Content     => '1<script></script>',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'drop external image',
        Data => {
            Content     => '1<img src="http://google.com"/>',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<Untitled%20Attachment>',
            },
        },
        Result => {
            Content => '

<div class="attachment-blocker" style="-moz-border-radius: 5px; -webkit-border-radius: 5px; background-color: #50B5FF10; border-radius: 5px; border: 1px solid #999; font-family:Geneva,Helvetica,Arial,sans-serif; font-size: 11px; margin: 5px 0; padding: 10px 20px; text-align: center;">
    <span>Zum Schutz Ihrer Privatsphäre wurden entfernte Inhalte blockiert.</span>
    <a href="index.pl?;LoadExternalImages=1;SessionID=123">Blockierte Inhalte laden.</a>
</div>
1',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'keep external image',
        Data => {
            Content     => '1<img src="http://google.com"/>',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<Untitled%20Attachment>',
            },
        },
        LoadExternalImages => 1,
        Result             => {
            Content     => '1<img src="http://google.com"/>',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'transform content charset',
        Data => {
            Content => <<EOF,
<!DOCTYPE html SYSTEM "about:legacy-compat">
<html lang="de-de">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
    <p>Some note about UTF8, UTF-8, utf8 and utf-8.</p>
    <p>Some note about ISO-8859-1 and iso-8859-1.</p>
    <p>This line must stay unchanged: charset=iso-8859-1</p>
</body>
</html>
EOF
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<Untitled%20Attachment>',
            },
        },
        LoadExternalImages => 1,
        Result             => {
            Content => <<EOF,
<!DOCTYPE html SYSTEM "about:legacy-compat">
<html lang="de-de">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
    <p>Some note about UTF8, UTF-8, utf8 and utf-8.</p>
    <p>Some note about ISO-8859-1 and iso-8859-1.</p>
    <p>This line must stay unchanged: charset=iso-8859-1</p>
</body>
</html>
EOF
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Charset - iso-8859-1',
        Data => {
            Content     => '<meta http-equiv="Content-Type" content="text/html; charset=\'iso-8859-1\'">',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        Attachments => {},
        URL         => 'Action=SomeAction;FileID=',
        Result      => {
            Content     => '<meta http-equiv="Content-Type" content="text/html; charset=\'utf-8\'">',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Charset - Windows-1252',
        Data => {
            Content     => '<meta http-equiv="Content-Type" content="text/html;charset=Windows-1252">',
            ContentType => 'text/html; charset=Windows-1252',
        },
        Attachments => {},
        URL         => 'Action=SomeAction;FileID=',
        Result      => {
            Content     => '<meta http-equiv="Content-Type" content="text/html;charset=utf-8">',
            ContentType => 'text/html; charset=utf-8',
        },
    },
    {
        Name => 'Charset - utf-8',
        Data => {
            Content     => '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">',
            ContentType => 'text/html; charset=utf-8',
        },
        Attachments => {},
        URL         => 'Action=SomeAction;FileID=',
        Result      => {
            Content     => '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">',
            ContentType => 'text/html; charset=utf-8',
        },
    },
    {
        Name => 'Charset - double quotes',
        Data => {
            Content     => '<meta http-equiv=\'Content-Type\' content=\'text/html; charset="utf-8"\'>',
            ContentType => 'text/html; charset="utf-8"',
        },
        Attachments => {},
        URL         => 'Action=SomeAction;FileID=',
        Result      => {
            Content     => '<meta http-equiv=\'Content-Type\' content=\'text/html; charset="utf-8"\'>',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Charset - no charset defined, see bug#9610',
        Data => {
            Content     => '<meta http-equiv="Content-Type" content="text/html">',
            ContentType => 'text/html',
        },
        Attachments => {},
        URL         => 'Action=SomeAction;FileID=',
        Result      => {
            Content     => '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Empty Content-ID',
        Data => {
            Content     => 'Link <a href="http://test.example">http://test.example</a>',
            ContentType => 'text/html; charset="iso-8859-1"',
        },
        URL         => 'Action=SomeAction;FileID=',
        Attachments => {
            0 => {
                ContentID => '<>',
            },
        },
        LoadExternalImages => 1,
        Result             => {
            Content     => 'Link <a href="http://test.example" target="_blank">http://test.example</a>',
            ContentType => 'text/html; charset="utf-8"',
        },
    },
    {
        Name => 'Standard - extra spaces after charset and = tokens',
        Data => {
            Content     => 'Some Content',
            ContentType => 'text/html; charset = "utf-8"',
        },
        Attachments => {},
        URL         => 'Action=SomeAction;FileID=',
        Result      => {
            Content     => 'Some Content',
            ContentType => 'text/html; charset = "utf-8"',
        },
    },
);

for my $Test (@Tests) {
    my %HTML = $LayoutObject->RichTextDocumentServe(
        %{$Test},
    );

    # Quote the expected text to avoid problems with special characters.
    $Test->{Result}->{Content} = quotemeta( $Test->{Result}->{Content} );

    # Check if the result contains the expected HTML structure between <body> tags.
    my $Contains = $HTML{Content} =~ m{$Test->{Result}->{Content}};

    $Self->True(
        $Contains,
        "$Test->{Name} - Content"
    );

    $Self->Is(
        $HTML{ContentType},
        $Test->{Result}->{ContentType},
        "$Test->{Name} - ContentType"
    );
}

1;
