// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.lib.starlarkdebug.server;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.ContinueExecutionResponse;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.DebugEvent;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.Error;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.EvaluateResponse;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.Frame;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.GetChildrenResponse;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.ListFramesResponse;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.PauseThreadResponse;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.PausedThread;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.Scope;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.SetBreakpointsResponse;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.StartDebuggingResponse;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.ThreadContinuedEvent;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.ThreadPausedEvent;
import com.google.devtools.build.lib.starlarkdebugging.StarlarkDebuggingProtos.Value;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.annotation.Nullable;
import net.starlark.java.eval.Debug;
import net.starlark.java.eval.StarlarkFunction;
import net.starlark.java.syntax.Location;

/**
 * Helper class for constructing event or response protos to be sent from the debug server to a
 * debugger client.
 */
final class DebugEventHelper {
  private DebugEventHelper() {}

  private static final long NO_SEQUENCE_NUMBER = 0;

  static DebugEvent error(String message) {
    return error(NO_SEQUENCE_NUMBER, message);
  }

  static DebugEvent error(long sequenceNumber, String message) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setError(Error.newBuilder().setMessage(message))
        .build();
  }

  static DebugEvent setBreakpointsResponse(long sequenceNumber) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setSetBreakpoints(SetBreakpointsResponse.getDefaultInstance())
        .build();
  }

  static DebugEvent continueExecutionResponse(long sequenceNumber) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setContinueExecution(ContinueExecutionResponse.getDefaultInstance())
        .build();
  }

  static DebugEvent evaluateResponse(long sequenceNumber, Value value) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setEvaluate(EvaluateResponse.newBuilder().setResult(value))
        .build();
  }

  static DebugEvent listFramesResponse(long sequenceNumber, Collection<Frame> frames) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setListFrames(ListFramesResponse.newBuilder().addAllFrame(frames))
        .build();
  }

  static DebugEvent startDebuggingResponse(long sequenceNumber) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setStartDebugging(StartDebuggingResponse.getDefaultInstance())
        .build();
  }

  static DebugEvent pauseThreadResponse(long sequenceNumber) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setPauseThread(PauseThreadResponse.getDefaultInstance())
        .build();
  }

  static DebugEvent getChildrenResponse(long sequenceNumber, Collection<Value> children) {
    return DebugEvent.newBuilder()
        .setSequenceNumber(sequenceNumber)
        .setGetChildren(GetChildrenResponse.newBuilder().addAllChildren(children))
        .build();
  }

  static DebugEvent threadPausedEvent(PausedThread thread) {
    return DebugEvent.newBuilder()
        .setThreadPaused(ThreadPausedEvent.newBuilder().setThread(thread))
        .build();
  }

  static DebugEvent threadContinuedEvent(long threadId) {
    return DebugEvent.newBuilder()
        .setThreadContinued(ThreadContinuedEvent.newBuilder().setThreadId(threadId))
        .build();
  }

  @Nullable
  static StarlarkDebuggingProtos.Location getLocationProto(@Nullable Location location) {
    if (location == null) {
      return null;
    }
    return StarlarkDebuggingProtos.Location.newBuilder()
        .setLineNumber(location.line())
        .setColumnNumber(location.column())
        .setPath(location.file())
        .build();
  }

  static StarlarkDebuggingProtos.Frame getFrameProto(ThreadObjectMap objectMap, Debug.Frame frame) {
    return StarlarkDebuggingProtos.Frame.newBuilder()
        .setFunctionName(frame.getFunction().getName())
        .addAllScope(getScopes(objectMap, frame))
        .setLocation(getLocationProto(frame.getLocation()))
        .build();
  }

  private static ImmutableList<Scope> getScopes(ThreadObjectMap objectMap, Debug.Frame frame) {
    Map<String, Object> moduleVars =
        frame.getFunction() instanceof StarlarkFunction
            ? ((StarlarkFunction) frame.getFunction()).getModule().getGlobals()
            : ImmutableMap.of();

    ImmutableMap<String, Object> localVars = frame.getLocals();
    if (localVars.isEmpty()) {
      return ImmutableList.of(getScope(objectMap, "global", moduleVars));
    }

    Map<String, Object> globalVars = new LinkedHashMap<>(moduleVars);
    // remove shadowed bindings
    localVars.keySet().forEach(globalVars::remove);

    return ImmutableList.of(
        getScope(objectMap, "local", localVars), getScope(objectMap, "global", globalVars));
  }

  private static StarlarkDebuggingProtos.Scope getScope(
      ThreadObjectMap objectMap, String name, Map<String, Object> bindings) {
    StarlarkDebuggingProtos.Scope.Builder builder =
        StarlarkDebuggingProtos.Scope.newBuilder().setName(name);
    bindings.forEach(
        (s, o) -> builder.addBinding(DebuggerSerialization.getValueProto(objectMap, s, o)));
    return builder.build();
  }

  static Debug.Stepping convertSteppingEnum(StarlarkDebuggingProtos.Stepping stepping) {
    switch (stepping) {
      case INTO:
        return Debug.Stepping.INTO;
      case OUT:
        return Debug.Stepping.OUT;
      case OVER:
        return Debug.Stepping.OVER;
      case NONE:
        return Debug.Stepping.NONE;
      case UNRECOGNIZED:
        // fall through to exception
    }
    throw new IllegalArgumentException("Unsupported stepping type");
  }
}
