class ExporterImpl implements Exporter {

    public List<File> exportReport(ExportSettings settings, List<Participant> participants, Trip trip,
                                   ResourceResolver resourceResolver, ActivityResolver activityResolver, AmountFactory amountFactory) {

        List<File> filesCreated = new ArrayList<>();

        StringBuilder fileNamePrefix = new StringBuilder(resourceResolver.resolve(R.string.fileExportPrefix))
                .append(FILE_NAME_SEPARATOR)
                .append(ExporterFileNameUtils.clean(trip.getName()));
        StringBuilder timestamp = new StringBuilder(ExporterFileNameUtils.getTimeStamp(resourceResolver.getLocale()));

        HtmlExportCharResolver htmlExportCharResolver = null;
        CsvExportCharResolver csvExportCharResolver = null;
        TxtExportCharResolver txtExportCharResolver = null;

        if (settings.isFormatHtml()) {
            htmlExportCharResolver = new HtmlExportCharResolver();
            htmlExportCharResolver.setLang(resourceResolver.getLocale().getLanguage());
        }
        if (settings.isFormatCsv()) {
            csvExportCharResolver = new CsvExportCharResolver();
        }
        if (settings.isFormatTxt()) {
            txtExportCharResolver = new TxtExportCharResolver();
        }

        if (participants.size() > 1 && settings.isSeparateFilesForIndividuals()) {
            ArrayList<Participant> participantsSubset;
            for (Participant p : participants) {
                participantsSubset = new ArrayList<>(1);
                participantsSubset.add(p);
                createAndWriteFiles(settings,
                        participantsSubset,
                        trip,
                        resourceResolver,
                        fileWriter,
                        filesCreated,
                        fileNamePrefix,
                        timestamp,
                        htmlExportCharResolver,
                        csvExportCharResolver,
                        txtExportCharResolver,
                        amountFactory);
            }
        } else {
            createAndWriteFiles(settings,
                    participants,
                    trip,
                    resourceResolver,
                    fileWriter,
                    filesCreated,
                    fileNamePrefix,
                    timestamp,
                    htmlExportCharResolver,
                    csvExportCharResolver,
                    txtExportCharResolver,
                    amountFactory);
        }

        StreamSender streamSender = new StreamSenderImpl();
        StringBuilder exportSubject = new StringBuilder()
                .append(resourceResolver.resolve(R.string.fileExportEmailSubjectPrefix))
                .append(SPACE)
                .append(trip.getName())
                .append(SPACE)
                .append(timestamp);

        if (activityResolver.getActivity() != null) {
            List<Uri> contentUrisFromFiles = FileUtils.getContentUrisFromFiles(filesCreated, TrickyTripperFileProvider.AUTHORITY);
            if (settings.getOutputChannel() != null) {
                streamSender.sendStream(
                        (Activity) activityResolver.getActivity(),
                        exportSubject.toString(),
                        resourceResolver.resolve(R.string.fileExportEmailContent),
                        contentUrisFromFiles, settings.getOutputChannel());
            }
        }

        return filesCreated;

    }

}

class ExporterImplTest {

    private final Pattern patternCsvIndividual;
    private final Pattern patternCsvAll;
    private final Pattern patternHtmlIndividual;
    private final Pattern patternHtmlAll;
    private final Pattern patternTxtIndividual;
    private final Pattern patternTxtAll;
    @SuppressWarnings("FieldCanBeLocal")
    private final boolean deleteCreatedFiles;
    private Exporter exporter;
    private Trip tripToExport;
    private ResourceResolver resourceResolver;
    private Participant participant;
    private AmountFactory amountFactory;
    private TestDataFactory factory;

    @Test
    public void testOutputTxtForAllSplit() {

        ExportSettings exportSettings = createExportSettings(true, true, true, true, false, false, true, false, true);
        List<File> result = exporter.exportReport(exportSettings, tripToExport.getParticipant(), tripToExport,
                resourceResolver,
                new ActivityResolver() {

                    @Override
                    public Object getActivity() {
                        return null;
                    }
                },
                amountFactory);

        Throwable exceptionCaught = null;
        try {
            Assert.assertEquals(3, result.size());
            Assert.assertTrue(patternTxtIndividual.matcher(result.get(0).getName()).matches());
            Assert.assertTrue(patternTxtIndividual.matcher(result.get(1).getName()).matches());
            Assert.assertTrue(patternTxtIndividual.matcher(result.get(2).getName()).matches());

            for (int i = 0; i < result.size(); i++) {
                String name;
                if (i == 0) {
                    name = factory.chris.getName();
                }
                else if (i == 1) {
                    name = factory.niko.getName();
                }
                else {
                    name = factory.wolfram.getName();
                }
                Assert.assertTrue(nameContains(result.get(i), name));
            }
        }
        catch (Exception e) {
            exceptionCaught = e;
        }
        finally {
            deleteCreatedFiles(result);
        }
        if (exceptionCaught != null) {
            throw new RuntimeException(exceptionCaught);
        }
    }

}