package name.abuchen.portfolio.datatransfer.pdf;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import name.abuchen.portfolio.datatransfer.pdf.PDFParser.Block;
import name.abuchen.portfolio.datatransfer.pdf.PDFParser.DocumentType;
import name.abuchen.portfolio.datatransfer.pdf.PDFParser.Transaction;
import name.abuchen.portfolio.model.BuySellEntry;
import name.abuchen.portfolio.model.Client;
import name.abuchen.portfolio.model.PortfolioTransaction;

public class JustTradePDFExtractor extends AbstractPDFExtractor
{

    private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("d LLL yyyy HH:mm:ss", //$NON-NLS-1$
                    Locale.GERMANY);

    public JustTradePDFExtractor(Client client)
    {
        super(client);

        addBankIdentifier("justTRADE"); //$NON-NLS-1$

        addBuyTransactionOld();
        addBuyTransaction();
    }

    @Override
    public String getPDFAuthor()
    {
        return "Sutor Bank"; //$NON-NLS-1$
    }

    @SuppressWarnings("nls")
    private void addBuyTransactionOld()
    {
        DocumentType type = new DocumentType("Wertpapier Abrechnung Kauf");
        this.addDocumentTyp(type);

        Transaction<BuySellEntry> pdfTransaction = new Transaction<>();
        pdfTransaction.subject(() -> {
            BuySellEntry entry = new BuySellEntry();
            entry.setType(PortfolioTransaction.Type.BUY);
            return entry;
        });

        Block firstRelevantLine = new Block("Stück .*");
        type.addBlock(firstRelevantLine);
        firstRelevantLine.set(pdfTransaction);
        pdfTransaction

                        .section("shares", "name", "isin", "wkn") //
                        .match("^Stück (?<shares>[\\d.,]+) (?<name>.*) (?<isin>\\S*) \\((?<wkn>\\S*)\\)$") //
                        .assign((t, v) -> {
                            t.setSecurity(getOrCreateSecurity(v));
                            t.setShares(asShares(v.get("shares")));
                        })

                        .section("date") //
                        .match("Schlusstag\\/\\-Zeit (?<date>.{10}) .*")
                        .assign((t, v) -> t.setDate(asDate(v.get("date"))))

                        .section("amount", "currency")
                        .match("Kurswert (?<amount>[0-9.]+(\\,[0-9]{2}))- (?<currency>[A-Z]{3})") //
                        .assign((t, v) -> {
                            t.setAmount(asAmount(v.get("amount")));
                            t.setCurrencyCode(v.get("currency"));
                        })

                        .wrap(BuySellEntryItem::new);
    }

    @SuppressWarnings("nls")
    private void addBuyTransaction()
    {

        // layout of pdf changed
        DocumentType newType = new DocumentType("Transaktionsart: Kauf");
        this.addDocumentTyp(newType);

        Transaction<BuySellEntry> pdfTransaction = new Transaction<>();
        pdfTransaction.subject(() -> {
            BuySellEntry entry = new BuySellEntry();
            entry.setType(PortfolioTransaction.Type.BUY);
            return entry;
        });

        Block firstRelevantLine = new Block("Produktbezeichnung - .*");
        newType.addBlock(firstRelevantLine);
        firstRelevantLine.set(pdfTransaction);
        pdfTransaction

                        .section("name", "isin", "currency") //
                        .match("Produktbezeichnung - (?<name>.*)").match(".*")
                        .match("Internationale Wertpapierkennnummer \\(ISIN\\): (?<isin>\\S*)")
                        .match("Währung: (?<currency>[A-Z]{3})").assign((t, v) -> {
                            t.setSecurity(getOrCreateSecurity(v));
                            newType.getCurrentContext().put("currency", v.get("currency"));
                        })

                        .section("date", "time") // length of date is 10 or 11, example: "2 Jun 2019" or "21 Jun 2019"
                        .match("Orderausführung Datum\\/Zeit: (?<date>.{11}).*(?<time>.{8}).*").assign((t, v) -> {
                            // if length of date is 11, we need to strip the trailing blank
                            LocalDateTime dateTime = LocalDateTime.parse(
                                            String.format("%s %s", v.get("date").stripTrailing(), v.get("time")), DATE_TIME_FORMAT);
                            t.setDate(dateTime);
                        })

                        .section("shares") //
                        .match("Stück\\/Nominale: (?<shares>[0-9.]+(\\,[0-9]{2})).*")
                        .assign((t, v) -> t.setShares(asShares(v.get("shares"))))

                        .section("amount").match("Ausmachender Betrag: (\\W{1})(?<amount>([0-9.]+)\\,([0-9]{2}))") //
                        .assign((t, v) -> {
                            t.setAmount(asAmount(v.get("amount")));
                            t.setCurrencyCode(asCurrencyCode(newType.getCurrentContext().get("currency")));
                        })

                        .wrap(BuySellEntryItem::new);
    }

    @Override
    public String getLabel()
    {
        return "Sutor justTRADE"; //$NON-NLS-1$
    }
}

@@ -956,32 +956,365 @@
 on();%0D%0A    %7D%0D%0A%0D%0A
+    private String stripTrailing(String value)%0D%0A    %7B%0D%0A        int right = value.length();%0D%0A        if (value.endsWith(%22 %22)) //$NON-NLS-1$%0D%0A        %7B%0D%0A            value = value.substring(0, right-1);%0D%0A        %7D%0D%0A        if (right == 0)%0D%0A        %7B%0D%0A            return %22%22; //$NON-NLS-1$%0D%0A        %7D%0D%0A        return value;%0D%0A    %7D%0D%0A    %0D%0A
     @Override%0D%0A 
@@ -4747,22 +4747,8 @@
 s%22, 
-v.get(%22date%22).
 stri
@@ -4757,16 +4757,29 @@
 railing(
+v.get(%22date%22)
 ), v.get

Fix to support new PDF format of justTrade