[LIB-8] Console output, properties, date utils
[snooker-score-api.git] / src / main / java / org / hedgecode / snooker / SnookerScoreApp.java
index 286c966..dbd2b9a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017. Developed by Hedgecode.
+ * Copyright (c) 2017-2019. Developed by Hedgecode.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.hedgecode.snooker;
 
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-
 import org.hedgecode.snooker.api.APIException;
 import org.hedgecode.snooker.api.Event;
 import org.hedgecode.snooker.api.Events;
+import org.hedgecode.snooker.api.Match;
+import org.hedgecode.snooker.api.Player;
+import org.hedgecode.snooker.api.Round;
+import org.hedgecode.snooker.api.Rounds;
 import org.hedgecode.snooker.api.Season;
+import org.hedgecode.snooker.api.Seeding;
+import org.hedgecode.snooker.api.Seedings;
+import org.hedgecode.snooker.api.SnookerScoreAPI;
 
 /**
  * Snooker Score Main Application.
@@ -31,68 +35,279 @@ import org.hedgecode.snooker.api.Season;
  */
 public final class SnookerScoreApp {
 
-    private static final String EMPTY = "";
-    private static final String DELIMITER =
-            "********************************************************************************";
-    private static final String[] WELCOME = {
-            "                    Welcome to Hedgecode Snooker Score API!                     ",
-            "                -----------------------------------------------                 ",
-            "         It is an API library for portal snooker.org, which contains            ",
-            "      the results of snooker competitions and other snooker information.        ",
-            "    This library provides a set of entity objects that can be used in client    ",
-            "    applications (to inform about the results of snooker), developed in Java.   "
-    };
-    private static final String CURRENT_EVENTS = "  Current Snooker Events:  ";
-    private static final String UPCOMING_EVENTS = "  Upcoming Snooker Events:  ";
-    private static final String INDENT = "     ";
-
-    private static final String DATE_FORMAT = "dd.MM.yyyy";
+    private static final String ARG_PREFIX = "^[-/]";
+    private static final String ARG_POSTFIX = "$";
+    private static final String ARG_QUIET_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_QUIET + ARG_POSTFIX;
+    private static final String ARG_SERVER_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_SERVER + ARG_POSTFIX;
+    private static final String ARG_PORT_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_PORT + ARG_POSTFIX;
+    private static final String ARG_HELP_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_HELP + ARG_POSTFIX;
+
+    private static final int INVALID_PORT = -1;
+    private static final int PORT_RANGE_MIN = 0;
+    private static final int PORT_RANGE_MAX = 65535;
+    private static final int PORT_RANGE_SYSTEM = 1024;
+    private static final String PORT_NUMBER_REGEX = "[0-9]+";
 
     private static final int UPCOMING_COUNT = 5;
+    private static final int TOP_SEEDING_COUNT = 10;
+
+    private static final String INDENT = "    ";
+    private static final String CURRENT_EVENTS = "Current Snooker Events:";
+    private static final String UPCOMING_EVENTS = "Upcoming Snooker Events:";
+    private static final String EVENT_ROUNDS = "Rounds of";
+    private static final String EVENT_SEEDING = "Seeding of";
 
     public static void main(String[] args) throws APIException
     {
-        System.out.println(EMPTY);
-        System.out.println(DELIMITER);
-        for (String line : WELCOME) {
-            System.out.println(line);
+        if (isHelpMode(args)) {
+
+            if (!isQuietMode(args)) {
+                printWelcome();
+            }
+            printHelp();
+
+        } else if (!isQuietMode(args)) {
+
+            printWelcome();
+
+            Events events = Snooker.uncachedAPI().getSeasonEvents(
+                    Season.CURRENT_SEASON
+            );
+            events.sortByDate();
+
+            printCurrentEvents(events);
+            printUpcomingEvents(events);
+
+        }
+
+        int serverPort = serverMode(args);
+        if (isValidPort(serverPort)) {
+            // todo: server mode
+        }
+    }
+
+    private static boolean isQuietMode(String[] args) {
+        for (String arg : args) {
+            if (arg.matches(ARG_QUIET_REGEX)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isHelpMode(String[] args) {
+        for (String arg : args) {
+            if (arg.matches(ARG_HELP_REGEX)) {
+                return true;
+            }
         }
+        return false;
+    }
 
-        Events events = Snooker.uncachedAPI().getSeasonEvents(
-                Season.CURRENT_SEASON
+
+    private static int serverMode(String[] args) {
+        boolean isServerMode = false;
+        int serverPort = Integer.parseInt(
+                SnookerScoreProperties.get("snooker.port.number")
         );
-        events.sortByDate();
+        boolean isPortArg = false;
+        for (String arg : args) {
+            if (isPortArg) {
+                if (arg.matches(PORT_NUMBER_REGEX)) {
+                    serverPort = Integer.parseInt(arg);
+                }
+                isPortArg = false;
+            } else if (arg.matches(ARG_PORT_REGEX)) {
+                isPortArg = true;
+            } else if (arg.matches(ARG_SERVER_REGEX)) {
+                isServerMode = true;
+            }
+        }
+        return isServerMode ? serverPort : INVALID_PORT;
+    }
+
+    private static boolean isValidPort(int portNumber) {
+        if (portNumber >= PORT_RANGE_MIN && portNumber <= PORT_RANGE_MAX) {
+            if (portNumber < PORT_RANGE_SYSTEM) {
+                SnookerScoreConsole.console(
+                        String.format(
+                                "%s: %s %d",
+                                "Warning",
+                                "Don't recommend using port numbers less than",
+                                PORT_RANGE_SYSTEM
+                        )
+                );
+            }
+            return true;
+        }
+        return false;
+    }
 
+    private static void printWelcome() {
+        SnookerScoreConsole.init();
+        SnookerScoreConsole.welcome();
+        SnookerScoreConsole.empty();
+        SnookerScoreConsole.delimiter();
+    }
+
+    private static void printHelp() {
+        SnookerScoreConsole.empty();
+        SnookerScoreConsole.help();
+        SnookerScoreConsole.empty();
+    }
+
+    private static void printCurrentEvents(Events events) {
         Events currentEvents = events.current();
         if (!currentEvents.isEmpty()) {
-            System.out.println(DELIMITER);
-            System.out.println(CURRENT_EVENTS);
+            SnookerScoreConsole.console(
+                    String.format("%s%s", INDENT, CURRENT_EVENTS)
+            );
+            for (Event currentEvent : currentEvents) {
+                printEvent(currentEvent, INDENT.concat(INDENT));
+            }
+            SnookerScoreConsole.delimiter();
         }
-        for (Event currentEvent : currentEvents) {
-            printEvent(currentEvent);
+    }
+
+    private static void printUpcomingEvents(Events events) {
+        Events upcomingEvents = events.upcoming();
+        if (!upcomingEvents.isEmpty()) {
+            SnookerScoreConsole.console(
+                    String.format("%s%s", INDENT, UPCOMING_EVENTS)
+            );
+            int count = 0;
+            for (Event upcomingEvent : upcomingEvents) {
+                printEvent(upcomingEvent, INDENT.concat(INDENT));
+                ++count;
+                if (count >= UPCOMING_COUNT) break;
+            }
+            SnookerScoreConsole.delimiter();
         }
+    }
 
-        System.out.println(DELIMITER);
-        System.out.println(UPCOMING_EVENTS);
+    private static void printEvent(Event event, String indent) {
+        SnookerScoreConsole.console(
+                String.format(
+                        "%s%s [%s - %s] (%s, %s)",
+                        indent,
+                        event.name(),
+                        SnookerDateUtils.formatDate(event.startDate()),
+                        SnookerDateUtils.formatDate(event.endDate()),
+                        event.country(),
+                        event.city()
+                )
+        );
+    }
 
-        int count = 0;
-        Events upcomingEvents = events.upcoming();
-        for (Event upcomingEvent : upcomingEvents) {
-            printEvent(upcomingEvent);
-            ++count;
-            if (count >= UPCOMING_COUNT) break;
+    private static void printPlayer(Player player) {
+        SnookerScoreConsole.console(
+                String.format(
+                        "%s%s %s [%s] (%s)",
+                        INDENT,
+                        player.surnameFirst() ? player.lastName() : player.firstName(),
+                        player.surnameFirst() ? player.firstName() : player.lastName(),
+                        SnookerDateUtils.formatDate(player.born()),
+                        player.nationality()
+                )
+        );
+    }
+
+    private static void printMatch(Match match) throws APIException {
+        SnookerScoreAPI api = Snooker.uncachedAPI();
+        Player player1 = api.getPlayer(match.player1Id());
+        Player player2 = api.getPlayer(match.player2Id());
+        SnookerScoreConsole.console(
+                String.format(
+                        "%s[%s %s - %s] %s %s %s-%s %s %s",
+                        INDENT,
+                        SnookerDateUtils.formatDate(match.startDate()),
+                        SnookerDateUtils.formatTime(match.startDate()),
+                        SnookerDateUtils.formatTime(match.endDate()),
+                        player1.surnameFirst() ? player1.lastName() : player1.firstName(),
+                        player1.surnameFirst() ? player1.firstName() : player1.lastName(),
+                        match.score1(),
+                        match.score2(),
+                        player2.surnameFirst() ? player2.lastName() : player2.firstName(),
+                        player2.surnameFirst() ? player2.firstName() : player2.lastName()
+                )
+        );
+    }
+
+    private static void printRounds(Rounds rounds, Event event) throws APIException {
+        if (!rounds.isEmpty()) {
+            rounds.sortByRound();
+            if (event != null) {
+                SnookerScoreConsole.console(
+                        String.format("%s%s %s:", INDENT, EVENT_ROUNDS, event.name())
+                );
+            }
+            for (Round round : rounds) {
+                printRound(round, event, INDENT.concat(INDENT));
+            }
+            SnookerScoreConsole.delimiter();
+        }
+    }
+
+    private static void printRound(Round round, Event event, String indent) throws APIException {
+        if (event == null || event.getId() != round.eventId()) {
+            SnookerScoreAPI api = Snooker.uncachedAPI();
+            Event roundEvent = api.getEvent(round.eventId());
+            SnookerScoreConsole.console(
+                    String.format(
+                            "%s%s. %s (%s)",
+                            indent,
+                            round.round(),
+                            round.roundName(),
+                            roundEvent.name()
+                    )
+            );
+        } else {
+            SnookerScoreConsole.console(
+                    String.format(
+                            "%s%s. %s",
+                            indent,
+                            round.round(),
+                            round.roundName()
+                    )
+            );
+        }
+    }
+
+    private static void printSeedings(Seedings seedings, Event event) throws APIException {
+        if (!seedings.isEmpty()) {
+            seedings.sortBySeeding();
+            if (event != null) {
+                SnookerScoreConsole.console(
+                        String.format(
+                                "%s%s %s (top %d):",
+                                INDENT,
+                                EVENT_SEEDING,
+                                event.name(),
+                                TOP_SEEDING_COUNT
+                        )
+                );
+            }
+            int count = 0;
+            for (Seeding seeding : seedings) {
+                printSeeding(seeding, INDENT.concat(INDENT));
+                ++count;
+                if (count >= TOP_SEEDING_COUNT) break;
+            }
+            SnookerScoreConsole.delimiter();
         }
-        System.out.println(DELIMITER);
-        System.out.println(EMPTY);
     }
 
-    private static void printEvent(Event event) {
-        final DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
-        System.out.println(
-                INDENT  + event.name()
-                        + " [" + dateFormat.format(event.startDate())
-                        + " - " + dateFormat.format(event.endDate()) + "]"
-                        + " (" + event.country() + ", " + event.city() + ")"
+    private static void printSeeding(Seeding seeding, String indent) throws APIException {
+        SnookerScoreAPI api = Snooker.uncachedAPI();
+        Player player = api.getPlayer(seeding.playerId());
+        SnookerScoreConsole.console(
+                String.format(
+                        "%s%s. %s %s",
+                        indent,
+                        seeding.seeding(),
+                        player.surnameFirst() ? player.lastName() : player.firstName(),
+                        player.surnameFirst() ? player.firstName() : player.lastName()
+                )
         );
     }