// Copyright 2023 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.packages;

import com.google.devtools.build.docgen.annot.DocCategory;
import java.util.Arrays;
import java.util.Map;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkFloat;
import net.starlark.java.eval.StarlarkInt;
import net.starlark.java.eval.StarlarkValue;
import net.starlark.java.eval.Structure;

/** Proto defines the "proto" Starlark module of utilities for protocol message processing. */
@StarlarkBuiltin(
    name = "proto",
    category = DocCategory.TOP_LEVEL_MODULE,
    doc = "A module for protocol message processing.")
public class Proto implements StarlarkValue {

  // Note: in due course this is likely to move to net.starlark.java.lib.proto.
  // Do not add functions that would not belong there!
  // Functions related to running the protocol compiler belong in proto_common.

  private Proto() {}

  public static final Proto INSTANCE = new Proto();

  @StarlarkMethod(
      name = "encode_text",
      doc =
          "Returns the struct argument's encoding as a text-format protocol message.\n"
              + "The data structure must be recursively composed of strings, ints, floats, or"
              + " bools, or structs, sequences, and dicts of these types.\n"
              + "<p>A struct is converted to a message. Fields are emitted in name order.\n"
              + "Each struct field whose value is None is ignored.\n"
              + "<p>A sequence (such as a list or tuple) is converted to a repeated field.\n"
              + "Its elements must not be sequences or dicts.\n"
              + "<p>A dict is converted to a repeated field of messages with fields named 'key' and"
              + " 'value'.\n"
              + "Entries are emitted in iteration (insertion) order.\n"
              + "The dict's keys must be strings or ints, and its values must not be sequences or"
              + " dicts.\n"
              + "Examples:<br><pre class=language-python>proto.encode_text(struct(field=123))\n"
              + "# field: 123\n\n"
              + "proto.encode_text(struct(field=True))\n"
              + "# field: true\n\n"
              + "proto.encode_text(struct(field=[1, 2, 3]))\n"
              + "# field: 1\n"
              + "# field: 2\n"
              + "# field: 3\n\n"
              + "proto.encode_text(struct(field='text', ignored_field=None))\n"
              + "# field: \"text\"\n\n"
              + "proto.encode_text(struct(field=struct(inner_field='text', ignored_field=None)))\n"
              + "# field {\n"
              + "#   inner_field: \"text\"\n"
              + "# }\n\n"
              + "proto.encode_text(struct(field=[struct(inner_field=1), struct(inner_field=2)]))\n"
              + "# field {\n"
              + "#   inner_field: 1\n"
              + "# }\n"
              + "# field {\n"
              + "#   inner_field: 2\n"
              + "# }\n\n"
              + "proto.encode_text(struct(field=struct(inner_field=struct(inner_inner_field='text'))))\n"
              + "# field {\n"
              + "#    inner_field {\n"
              + "#     inner_inner_field: \"text\"\n"
              + "#   }\n"
              + "# }\n\n"
              + "proto.encode_text(struct(foo={4: 3, 2: 1}))\n"
              + "# foo: {\n"
              + "#   key: 4\n"
              + "#   value: 3\n"
              + "# }\n"
              + "# foo: {\n"
              + "#   key: 2\n"
              + "#   value: 1\n"
              + "# }\n"
              + "</pre>",
      parameters = {@Param(name = "x")})
  public String encodeText(Structure x) throws EvalException {
    TextEncoder enc = new TextEncoder();
    enc.message(x);
    return enc.out.toString();
  }

  private static final class TextEncoder {

    private final StringBuilder out = new StringBuilder();
    private int indent = 0;

    // Encodes Structure x as a protocol message.
    private void message(Structure x) throws EvalException {
      // For determinism, sort fields.
      String[] fields = x.getFieldNames().toArray(new String[0]);
      Arrays.sort(fields);
      for (String field : fields) {
        try {
          field(field, x.getValue(field));
        } catch (EvalException ex) {
          throw Starlark.errorf("in %s field .%s: %s", Starlark.type(x), field, ex.getMessage());
        }
      }
    }

    // Encodes Structure field (name, v) as a message field
    // (a repeated field, if v is a dict or sequence.)
    private void field(String name, Object v) throws EvalException {
      // dict?
      if (v instanceof Dict) {
        Dict<?, ?> dict = (Dict<?, ?>) v;
        for (Map.Entry<?, ?> entry : dict.entrySet()) {
          Object key = entry.getKey();
          if (!(key instanceof String || key instanceof StarlarkInt)) {
            throw Starlark.errorf(
                "invalid dict key: got %s, want int or string", Starlark.type(key));
          }
          emitLine(name, " {");
          indent++;
          fieldElement("key", key); // can't fail
          try {
            fieldElement("value", entry.getValue());
          } catch (EvalException ex) {
            throw Starlark.errorf(
                "in value for dict key %s: %s", Starlark.repr(key), ex.getMessage());
          }
          indent--;
          emitLine("}");
        }
        return;
      }

      // list or tuple?
      if (v instanceof Sequence) {
        int i = 0;
        for (Object item : (Sequence<?>) v) {
          try {
            fieldElement(name, item);
          } catch (EvalException ex) {
            throw Starlark.errorf("at %s index %d: %s", Starlark.type(v), i, ex.getMessage());
          }
          i++;
        }
        return;
      }

      // non-repeated field
      if (v == Starlark.NONE) {
        return;
      }
      fieldElement(name, v);
    }

    // Emits field (name, v) as a message field, or one element of a repeated field.
    // v must be an int, float, string, bool, or Structure.
    private void fieldElement(String name, Object v) throws EvalException {
      if (v instanceof Structure) {
        emitLine(name, " {");
        indent++;
        message((Structure) v);
        indent--;
        emitLine("}");

      } else if (v instanceof String) {
        String s = (String) v;
        emitLine(
            name, ": \"", s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n"), "\"");

      } else if (v instanceof StarlarkInt || v instanceof Boolean) {
        emitLine(name, ": ", v.toString());
      } else if (v instanceof StarlarkFloat) {
        String s = v.toString();
        // Encoding to textproto via proto.encode_text requires "inf" for "+inf".
        if (s.equals("+inf")) {
          s = "inf";
        }
        emitLine(name, ": ", s);
      } else {
        throw Starlark.errorf("got %s, want string, int, float, bool, or struct", Starlark.type(v));
      }
    }

    // Emits items on an indented line.
    private void emitLine(String... items) {
      for (int i = 0; i < indent; i++) {
        out.append("  ");
      }
      for (String item : items) {
        out.append(item);
      }
      out.append('\n');
    }
  }
}
