/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.gossip.examples;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Arrays;
import org.apache.gossip.GossipSettings;
import org.apache.gossip.RemoteMember;
import org.apache.gossip.crdt.GrowOnlyCounter;
import org.apache.gossip.crdt.OrSet;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.apache.gossip.model.SharedDataMessage;

public class StandAloneNodeCrdtOrSet {

  private static ExampleCommon common = new ExampleCommon();

  public static void main(String[] args) throws InterruptedException, IOException {
    args = common.checkArgsForClearFlag(args);
    GossipSettings s = new GossipSettings();
    s.setWindowSize(1000);
    s.setGossipInterval(100);
    GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster("mycluster")
            .uri(URI.create(args[0]))
            .id(args[1])
            .gossipMembers(
                    Arrays.asList(new RemoteMember("mycluster", URI.create(args[2]), args[3])))
            .gossipSettings(s)
            .build();
    gossipService.init();

    new Thread(() -> {
      while (true) {
        common.optionallyClearTerminal();
        System.out.println("Live: " + gossipService.getLiveMembers());
        System.out.println("Dead: " + gossipService.getDeadMembers());
        System.out.println("---------- " + (gossipService.findCrdt("abc") == null ? ""
                : gossipService.findCrdt("abc").value()));
        System.out.println("********** " + gossipService.findCrdt("abc"));
        System.out.println("^^^^^^^^^^ " + (gossipService.findCrdt("def") == null ? ""
                : gossipService.findCrdt("def").value()));
        System.out.println("$$$$$$$$$$ " + gossipService.findCrdt("def"));
        try {
          Thread.sleep(2000);
        } catch (Exception e) {
        }
      }
    }).start();

    String line = null;
    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
      while ((line = br.readLine()) != null) {
        System.out.println(line);
        char op = line.charAt(0);
        String val = line.substring(2);
        if (op == 'a') {
          addData(val, gossipService);
        } else if (op == 'r') {
          removeData(val, gossipService);
        } else if (op == 'g') {
          gcount(val, gossipService);
        }
        if (op == 'l') {
          listen(val, gossipService);
        }
      }
    }
  }
  
  private static void listen(String val, GossipManager gossipManager) {
    gossipManager.registerSharedDataSubscriber((key, oldValue, newValue) -> {
      if (key.equals(val)) {
        System.out.println("Event Handler fired! " + oldValue + " " + newValue);
      }
    });
  }
  
  private static void gcount(String val, GossipManager gossipManager) {
    GrowOnlyCounter c = (GrowOnlyCounter) gossipManager.findCrdt("def");
    Long l = Long.valueOf(val);
    if (c == null) {
      c = new GrowOnlyCounter(new GrowOnlyCounter.Builder(gossipManager).increment((l)));
    } else {
      c = new GrowOnlyCounter(c, new GrowOnlyCounter.Builder(gossipManager).increment((l)));
    }
    SharedDataMessage m = new SharedDataMessage();
    m.setExpireAt(Long.MAX_VALUE);
    m.setKey("def");
    m.setPayload(c);
    m.setTimestamp(System.currentTimeMillis());
    gossipManager.merge(m);
  }

  private static void removeData(String val, GossipManager gossipService) {
    @SuppressWarnings("unchecked")
    OrSet<String> s = (OrSet<String>) gossipService.findCrdt("abc");
    SharedDataMessage m = new SharedDataMessage();
    m.setExpireAt(Long.MAX_VALUE);
    m.setKey("abc");
    m.setPayload(new OrSet<String>(s, new OrSet.Builder<String>().remove(val)));
    m.setTimestamp(System.currentTimeMillis());
    gossipService.merge(m);
  }

  private static void addData(String val, GossipManager gossipService) {
    SharedDataMessage m = new SharedDataMessage();
    m.setExpireAt(Long.MAX_VALUE);
    m.setKey("abc");
    m.setPayload(new OrSet<String>(val));
    m.setTimestamp(System.currentTimeMillis());
    gossipService.merge(m);
  }

}
