// Copyright 2017 Google Inc.
//
// Licensed 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 codeu.chat;

import java.io.IOException;
import java.io.File;

import codeu.chat.common.Relay;
import codeu.chat.common.Secret;
import codeu.chat.server.NoOpRelay;
import codeu.chat.server.RemoteRelay;
import codeu.chat.server.Server;
import codeu.chat.util.Logger;
import codeu.chat.util.RemoteAddress;
import codeu.chat.util.Uuid;
import codeu.chat.util.connections.ClientConnectionSource;
import codeu.chat.util.connections.Connection;
import codeu.chat.util.connections.ConnectionSource;
import codeu.chat.util.connections.ServerConnectionSource;

final class ServerMain {

  private static final Logger.Log LOG = Logger.newLog(ServerMain.class);

  public static void main(String[] args) {

    Logger.enableConsoleOutput();

    try {
      Logger.enableFileOutput("chat_server_log.log");
    } catch (IOException ex) {
      LOG.error(ex, "Failed to set logger to write to file");
    }

    LOG.info("============================= START OF LOG =============================");

    Uuid id = null;
    Secret secret = null;
    int port = -1;
    // This is the directory where it is safe to store data accross runs
    // of the server.
    File persistentPath = null;
    RemoteAddress relayAddress = null;

    try {
      id = Uuid.parse(args[0]);
      secret = Secret.parse(args[1]);
      port = Integer.parseInt(args[2]);
      persistentPath = new File(args[3]);
      relayAddress = args.length > 4 ? RemoteAddress.parse(args[4]) : null;
    } catch (Exception ex) {
      LOG.error(ex, "Failed to read command arguments");
      System.exit(1);
    }

    if (!persistentPath.isDirectory()) {
      LOG.error("%s does not exist", persistentPath);
      System.exit(1);
    }

    try (
        final ConnectionSource serverSource = ServerConnectionSource.forPort(port);
        final ConnectionSource relaySource = relayAddress == null ? null : new ClientConnectionSource(relayAddress.host, relayAddress.port)
    ) {

      LOG.info("Starting server...");
      runServer(id, secret, serverSource, relaySource, persistentPath);

    } catch (IOException ex) {

      LOG.error(ex, "Failed to establish connections");

    }
  }

  private static void runServer(Uuid id,
                                Secret secret,
                                ConnectionSource serverSource,
                                ConnectionSource relaySource, File persistentPath) {

    final Relay relay = relaySource == null ?
                        new NoOpRelay() :
                        new RemoteRelay(relaySource);

    final Server server = new Server(id, secret, relay, persistentPath);

    LOG.info("Created server.");

    while (true) {

      try {

        LOG.info("Established connection...");
        final Connection connection = serverSource.connect();
        LOG.info("Connection established.");

        server.handleConnection(connection);

      } catch (IOException ex) {
        LOG.error(ex, "Failed to establish connection.");
      }
    }
  }
}


@@ -3120,16 +3120,72 @@
 ource);%0A
+    %0A    File fp = new File(persistantPath, 'path.txt');
 %0A    fin
@@ -3233,30 +3233,18 @@
  relay, 
+f
 p
-ersistentPath
 );%0A%0A    

Create file for Server's constructor