[LIB-8] URL and HTML tag processing, new entities fields
[snooker-score-api.git] / src / main / java / org / hedgecode / snooker / SnookerScoreApp.java
1 /*
2  * Copyright (c) 2017-2019. Developed by Hedgecode.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.hedgecode.snooker;
18
19 import org.hedgecode.snooker.api.APIException;
20 import org.hedgecode.snooker.api.Event;
21 import org.hedgecode.snooker.api.Events;
22 import org.hedgecode.snooker.api.Match;
23 import org.hedgecode.snooker.api.Player;
24 import org.hedgecode.snooker.api.Round;
25 import org.hedgecode.snooker.api.Rounds;
26 import org.hedgecode.snooker.api.Season;
27 import org.hedgecode.snooker.api.Seeding;
28 import org.hedgecode.snooker.api.Seedings;
29 import org.hedgecode.snooker.api.SnookerScoreAPI;
30
31 /**
32  * Snooker Score Main Application.
33  *
34  * @author Dmitry Samoshin aka gotty
35  */
36 public final class SnookerScoreApp {
37
38     private static final String ARG_PREFIX = "^[-/]";
39     private static final String ARG_POSTFIX = "$";
40     private static final String ARG_QUIET_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_QUIET + ARG_POSTFIX;
41     private static final String ARG_SERVER_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_SERVER + ARG_POSTFIX;
42     private static final String ARG_PORT_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_PORT + ARG_POSTFIX;
43     private static final String ARG_HELP_REGEX = ARG_PREFIX + SnookerScoreConsole.ARG_HELP + ARG_POSTFIX;
44
45     private static final int INVALID_PORT = -1;
46     private static final int PORT_RANGE_MIN = 0;
47     private static final int PORT_RANGE_MAX = 65535;
48     private static final int PORT_RANGE_SYSTEM = 1024;
49     private static final String PORT_NUMBER_REGEX = "[0-9]+";
50
51     private static final int UPCOMING_COUNT = 5;
52     private static final int TOP_SEEDING_COUNT = 10;
53
54     private static final String INDENT = "    ";
55     private static final String CURRENT_EVENTS = "Current Snooker Events:";
56     private static final String UPCOMING_EVENTS = "Upcoming Snooker Events:";
57     private static final String EVENT_ROUNDS = "Rounds of";
58     private static final String EVENT_SEEDING = "Seeding of";
59
60     public static void main(String[] args) throws APIException
61     {
62         if (isHelpMode(args)) {
63
64             if (!isQuietMode(args)) {
65                 printWelcome();
66             }
67             printHelp();
68
69         } else if (!isQuietMode(args)) {
70
71             printWelcome();
72
73             Events events = Snooker.uncachedAPI().getSeasonEvents(
74                     Season.CURRENT_SEASON
75             );
76             events.sortByDate();
77
78             printCurrentEvents(events);
79             printUpcomingEvents(events);
80
81         }
82
83         int serverPort = serverMode(args);
84         if (isValidPort(serverPort)) {
85             // todo: server mode
86         }
87     }
88
89     private static boolean isQuietMode(String[] args) {
90         for (String arg : args) {
91             if (arg.matches(ARG_QUIET_REGEX)) {
92                 return true;
93             }
94         }
95         return false;
96     }
97
98     private static boolean isHelpMode(String[] args) {
99         for (String arg : args) {
100             if (arg.matches(ARG_HELP_REGEX)) {
101                 return true;
102             }
103         }
104         return false;
105     }
106
107
108     private static int serverMode(String[] args) {
109         boolean isServerMode = false;
110         int serverPort = Integer.parseInt(
111                 SnookerScoreProperties.get("snooker.port.number")
112         );
113         boolean isPortArg = false;
114         for (String arg : args) {
115             if (isPortArg) {
116                 if (arg.matches(PORT_NUMBER_REGEX)) {
117                     serverPort = Integer.parseInt(arg);
118                 }
119                 isPortArg = false;
120             } else if (arg.matches(ARG_PORT_REGEX)) {
121                 isPortArg = true;
122             } else if (arg.matches(ARG_SERVER_REGEX)) {
123                 isServerMode = true;
124             }
125         }
126         return isServerMode ? serverPort : INVALID_PORT;
127     }
128
129     private static boolean isValidPort(int portNumber) {
130         if (portNumber >= PORT_RANGE_MIN && portNumber <= PORT_RANGE_MAX) {
131             if (portNumber < PORT_RANGE_SYSTEM) {
132                 SnookerScoreConsole.console(
133                         String.format(
134                                 "%s: %s %d",
135                                 "Warning",
136                                 "Don't recommend using port numbers less than",
137                                 PORT_RANGE_SYSTEM
138                         )
139                 );
140             }
141             return true;
142         }
143         return false;
144     }
145
146     private static void printWelcome() {
147         SnookerScoreConsole.init();
148         SnookerScoreConsole.welcome();
149         SnookerScoreConsole.empty();
150         SnookerScoreConsole.delimiter();
151     }
152
153     private static void printHelp() {
154         SnookerScoreConsole.empty();
155         SnookerScoreConsole.help();
156         SnookerScoreConsole.empty();
157     }
158
159     private static void printCurrentEvents(Events events) {
160         Events currentEvents = events.current();
161         if (!currentEvents.isEmpty()) {
162             SnookerScoreConsole.console(
163                     String.format("%s%s", INDENT, CURRENT_EVENTS)
164             );
165             for (Event currentEvent : currentEvents) {
166                 printEvent(currentEvent, INDENT.concat(INDENT));
167             }
168             SnookerScoreConsole.delimiter();
169         }
170     }
171
172     private static void printUpcomingEvents(Events events) {
173         Events upcomingEvents = events.upcoming();
174         if (!upcomingEvents.isEmpty()) {
175             SnookerScoreConsole.console(
176                     String.format("%s%s", INDENT, UPCOMING_EVENTS)
177             );
178             int count = 0;
179             for (Event upcomingEvent : upcomingEvents) {
180                 printEvent(upcomingEvent, INDENT.concat(INDENT));
181                 ++count;
182                 if (count >= UPCOMING_COUNT) break;
183             }
184             SnookerScoreConsole.delimiter();
185         }
186     }
187
188     private static void printEvent(Event event, String indent) {
189         SnookerScoreConsole.console(
190                 String.format(
191                         "%s%s [%s - %s] (%s, %s)",
192                         indent,
193                         event.name(),
194                         SnookerDateUtils.formatDate(event.startDate()),
195                         SnookerDateUtils.formatDate(event.endDate()),
196                         event.country(),
197                         event.city()
198                 )
199         );
200     }
201
202     private static void printPlayer(Player player) throws APIException {
203         SnookerScoreConsole.console(
204                 String.format(
205                         "%s%s [%s] (%s)",
206                         INDENT,
207                         player.fullName(),
208                         SnookerDateUtils.formatDate(player.born()),
209                         player.nationality()
210                 )
211         );
212     }
213
214     private static void printMatch(Match match) throws APIException {
215         SnookerScoreAPI api = Snooker.uncachedAPI();
216         Player player1 = api.getPlayer(match.player1Id());
217         Player player2 = api.getPlayer(match.player2Id());
218         SnookerScoreConsole.console(
219                 String.format(
220                         "%s[%s %s - %s] %s %s-%s %s",
221                         INDENT,
222                         SnookerDateUtils.formatDate(match.startDate()),
223                         SnookerDateUtils.formatTime(match.startDate()),
224                         SnookerDateUtils.formatTime(match.endDate()),
225                         player1.fullName(),
226                         match.score1(),
227                         match.score2(),
228                         player2.fullName()
229                 )
230         );
231     }
232
233     private static void printRounds(Rounds rounds, Event event) throws APIException {
234         if (!rounds.isEmpty()) {
235             rounds.sortByRound();
236             if (event != null) {
237                 SnookerScoreConsole.console(
238                         String.format("%s%s %s:", INDENT, EVENT_ROUNDS, event.name())
239                 );
240             }
241             for (Round round : rounds) {
242                 printRound(round, event, INDENT.concat(INDENT));
243             }
244             SnookerScoreConsole.delimiter();
245         }
246     }
247
248     private static void printRound(Round round, Event event, String indent) throws APIException {
249         if (event == null || event.getId() != round.eventId()) {
250             SnookerScoreAPI api = Snooker.uncachedAPI();
251             Event roundEvent = api.getEvent(round.eventId());
252             SnookerScoreConsole.console(
253                     String.format(
254                             "%s%s. %s (%s)",
255                             indent,
256                             round.round(),
257                             round.roundName(),
258                             roundEvent.name()
259                     )
260             );
261         } else {
262             SnookerScoreConsole.console(
263                     String.format(
264                             "%s%s. %s",
265                             indent,
266                             round.round(),
267                             round.roundName()
268                     )
269             );
270         }
271     }
272
273     private static void printSeedings(Seedings seedings, Event event) throws APIException {
274         if (!seedings.isEmpty()) {
275             seedings.sortBySeeding();
276             if (event != null) {
277                 SnookerScoreConsole.console(
278                         String.format(
279                                 "%s%s %s (top %d):",
280                                 INDENT,
281                                 EVENT_SEEDING,
282                                 event.name(),
283                                 TOP_SEEDING_COUNT
284                         )
285                 );
286             }
287             int count = 0;
288             for (Seeding seeding : seedings) {
289                 printSeeding(seeding, INDENT.concat(INDENT));
290                 ++count;
291                 if (count >= TOP_SEEDING_COUNT) break;
292             }
293             SnookerScoreConsole.delimiter();
294         }
295     }
296
297     private static void printSeeding(Seeding seeding, String indent) throws APIException {
298         SnookerScoreAPI api = Snooker.uncachedAPI();
299         Player player = api.getPlayer(seeding.playerId());
300         SnookerScoreConsole.console(
301                 String.format(
302                         "%s%s. %s",
303                         indent,
304                         seeding.seeding(),
305                         player.fullName()
306                 )
307         );
308     }
309
310 }