/*
 * Copyright 2000-2011 JetBrains s.r.o.
 *
 * 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 jetbrains.buildServer.nuget.server.feed.server.process;

import jetbrains.buildServer.controllers.admin.logs.LogViewUtil;
import jetbrains.buildServer.nuget.server.feed.server.NuGetServerRunnerSettings;
import jetbrains.buildServer.nuget.server.feed.server.NuGetServerStatus;
import jetbrains.buildServer.nuget.server.feed.server.NuGetServerStatusHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Eugene Petrenko (eugene.petrenko@gmail.com)
 *         Date: 01.11.11 17:09
 */
public class NuGetServerStatusHolderImpl implements NuGetServerStatusHolder {
  private final AtomicReference<State> myState = new AtomicReference<State>(INITIAL_STATE);
  private final NuGetServerRunnerSettings mySettings;

  public NuGetServerStatusHolderImpl(@NotNull final NuGetServerRunnerSettings settings) {
    mySettings = settings;
  }

  @NotNull
  public NuGetServerStatus getStatus() {
    final State state = getState();
    final boolean isEnabled = mySettings.isNuGetFeedEnabled();
    final String logsSlice = NuGetServerStatusHolderImpl.this.getLogsSlice();

    return new NuGetServerStatus() {
      public boolean isRunning() {
        return state.isRunning();
      }

      public boolean isScheduledToStart() {
        return !isRunning() && isEnabled;
      }

      public Boolean getServerAccessible() {
        return state.isServerAccessible();
      }

      @NotNull
      public String getLogsSlice() {
        return logsSlice;
      }
    };
  }

  @NotNull
  private State getState() {
    return myState.get();
  }

  @NotNull
  public String getLogsSlice() {
    final File logFilePath = mySettings.getLogFilePath();
    try {
      return LogViewUtil.getLogTail(logFilePath);
    } catch (IOException e) {
      return "Failed to open log file: " + logFilePath;
    }
  }


  public void startingServer() {
    myState.set(getState().setRunning());
  }

  public void stoppingServer() {
    myState.set(getState().setStopping());
  }

  public void pingSucceeded() {
    myState.set(getState().setPingSucceeded());
  }

  public void pingFailed() {
    myState.set(getState().setPingFailed());
  }

  public void setRunning() {
    startingServer();
  }

  private static class State {
    private final boolean myIsRunning;
    private final Boolean myIsServerAccessible;

    private State(boolean isRunning, @Nullable Boolean isServerAccessible) {
      myIsRunning = isRunning;
      myIsServerAccessible = isServerAccessible;
    }

    public boolean isRunning() {
      return myIsRunning;
    }

    @Nullable
    public Boolean isServerAccessible() {
      return myIsServerAccessible;
    }

    public State setRunning() {
      return new State(true, myIsServerAccessible);
    }

    public State setStopping() {
      return new State(false, myIsServerAccessible);
    }

    public State setPingSucceeded() {
      return new State(isRunning(), true);
    }

    public State setPingFailed() {
      return new State(isRunning(), false);
    }
  }

  private static final State INITIAL_STATE = new State(false, null);
}

@@ -674,24 +674,72 @@
 process;%0D%0A%0D%0A
+import com.intellij.openapi.diagnostic.Logger;%0D%0A
 import jetbr
@@ -1024,24 +1024,71 @@
 tusHolder;%0D%0A
+import jetbrains.buildServer.util.StringUtil;%0D%0A
 import org.j
@@ -1448,16 +1448,120 @@
 lder %7B%0D%0A
+  private static final Logger LOG = Logger.getInstance(NuGetServerStatusHolderImpl.class.getName());%0D%0A%0D%0A
   privat
@@ -2687,22 +2687,38 @@
 %0D%0A      
-return
+final String logTail =
  LogView
@@ -2744,24 +2744,109 @@
 FilePath);%0D%0A
+      if (!StringUtil.isEmptyOrSpaces(logTail)) %7B%0D%0A        return logTail;%0D%0A      %7D%0D%0A
     %7D catch 
@@ -2870,23 +2870,25 @@
 %0D%0A      
-return 
+LOG.warn(
 %22Failed 
@@ -2898,16 +2898,17 @@
 open log
+s
  file: %22
@@ -2921,16 +2921,17 @@
 FilePath
+)
 ;%0D%0A    %7D
@@ -2928,24 +2928,79 @@
 h);%0D%0A    %7D%0D%0A
+    return %22Failed to open log file: %22 + logFilePath;%0D%0A
   %7D%0D%0A%0D%0A%0D%0A  p

check possible nulls