class Split implements Command {

    @Override
    public void run() throws IOException, DecoderException {
        String action = ((String) args.getOptionSet().nonOptionArguments().get(2)).toLowerCase();
        SplitAction splitAction = SplitAction.valueOf(action);
        Set<String> tableSet = tableSet(admin, args);
        Map<String, List<byte[]>> splitMap = splitAction.split(tableSet, args);

        if (!args.isForceProceed() && !Util.askProceed()) return;

        for (Map.Entry<String, List<byte[]>> entry : splitMap.entrySet()) {
            String tableName = entry.getKey();
            try (HTable table = new HTable(admin.getConfiguration(), tableName)) {
                for (byte[] splitPoint : entry.getValue()) {
                    System.out.print("splitting - " + tableName + " - " + Bytes.toStringBinary(splitPoint));
                    try {
                        for (int i = 0; i < Constant.TRY_MAX; i++) {
                            try {
                                split(table, splitPoint);
                                break;
                            } catch (NotServingRegionException e) {
                                Thread.sleep(Constant.WAIT_INTERVAL_MS);
                            }
                            if (i == Constant.TRY_MAX - 1)
                                throw new RuntimeException("Splitting is not finished in " + (Constant.TRY_MAX * Constant.WAIT_INTERVAL_MS / 1000) + " seconds.");
                        }
                    } catch (IOException e) {
                        if (!e.getMessage().contains("should not give a splitkey which equals to startkey")) throw e;
                        System.out.println(" - SKIPPING");
                        continue;
                    }
                    System.out.println(" - OK");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public  Split(HBaseAdmin admin, Args args);

}