001package apps.util.issuereporter;
002
003import java.io.File;
004import java.io.IOException;
005import java.nio.file.*;
006import java.util.*;
007
008import jmri.profile.Profile;
009import jmri.profile.ProfileManager;
010import jmri.util.prefs.InitializationException;
011
012import org.jdom2.JDOMException;
013
014/**
015 *
016 * @author rhwood
017 */
018public class BugReport extends IssueReport {
019
020    private boolean includeProfile;
021    private final boolean includeSysInfo;
022    private final boolean includeLogs;
023    private final List<File> files = new ArrayList<>();
024
025    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BugReport.class);
026
027    public BugReport(String title, String body, boolean includeProfile, boolean includeSysInfo, boolean includeLogs) {
028        super(title, body);
029        this.includeProfile = includeProfile;
030        this.includeSysInfo = includeSysInfo;
031        this.includeLogs = includeLogs;
032    }
033
034    @Override
035    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE",
036                justification="Null check in stream.forEach() is embedded, beyond our control")
037    public void prepare() {
038        title = Bundle.getMessage(Locale.US, "bug.title", title);
039        if (!tooLong) {
040            try {
041                Path dir = Files.createTempDirectory("jmri-issue-report-" + new Date().getTime());
042                if (includeLogs) {
043                    Files.copy(new File(System.getProperty("jmri.log.path"), "session.log").toPath(), dir.resolve("session.log"), StandardCopyOption.REPLACE_EXISTING);
044                }
045                if (includeProfile) {
046                    Profile profile = ProfileManager.getDefault().getActiveProfile();
047                    if (profile != null) {
048                        File archive = new File(dir.toFile(), "profile.zip");
049                        ProfileManager.getDefault().export(profile, archive, false, false);
050                    }
051                }
052                if (includeSysInfo) {
053                    getSysInfoFile(dir);
054                }
055                try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
056                    stream.forEach(p -> files.add(p.toFile()));
057                }
058            } catch (IOException | JDOMException | InitializationException | NullPointerException ex) {
059                log.error("Unable to include profile in report.", ex);
060                includeProfile = false;
061            }
062            body = Bundle.getMessage(Locale.US,
063                    "bug.body",
064                    !files.isEmpty() ? Bundle.getMessage("instructions.paste.files") : "",
065                    body,
066                    getSimpleContext(),
067                    getIssueFooter());
068        } else {
069            body = Bundle.getMessage("instructions.paste.414");
070        }
071    }
072
073    private void getSysInfoFile(Path path) {
074        Path file = path.resolve("systemInfo.txt");
075        try {
076            Files.createFile(file);
077            Files.write(file, new SystemInfo(false).asList(), StandardOpenOption.TRUNCATE_EXISTING);
078        } catch (IOException ex) {
079            log.error("Exception writing system info", ex);
080        }
081    }
082
083    @Override
084    public List<File> getAttachments() {
085        return files;
086    }
087}