package my;

import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.StringBuilder;
import java.util.Objects;
import org.pkl.config.java.mapper.Named;
import org.pkl.config.java.mapper.NonNull;
import org.pkl.core.Duration;

public final class Mod {
  private Mod() {
  }

  private static void appendProperty(StringBuilder builder, String name, Object value) {
    builder.append("\n  ").append(name).append(" = ");
    String[] lines = Objects.toString(value).split("\n");
    builder.append(lines[0]);
    for (int i = 1; i < lines.length; i++) {
      builder.append("\n  ").append(lines[i]);
    }
  }

  public abstract static class Foo {
    protected final long one;

    protected Foo(@Named("one") long one) {
      this.one = one;
    }

    public long getOne() {
      return one;
    }
  }

  public static class None extends Foo {
    public None(@Named("one") long one) {
      super(one);
    }

    public None withOne(long one) {
      return new None(one);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (obj == null) return false;
      if (this.getClass() != obj.getClass()) return false;
      None other = (None) obj;
      if (!Objects.equals(this.one, other.one)) return false;
      return true;
    }

    @Override
    public int hashCode() {
      int result = 1;
      result = 31 * result + Objects.hashCode(this.one);
      return result;
    }

    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder(100);
      builder.append(None.class.getSimpleName()).append(" {");
      appendProperty(builder, "one", this.one);
      builder.append("\n}");
      return builder.toString();
    }
  }

  public static class Bar extends None {
    protected final String two;

    public Bar(@Named("one") long one, @Named("two") String two) {
      super(one);
      this.two = two;
    }

    public Bar withOne(long one) {
      return new Bar(one, two);
    }

    public String getTwo() {
      return two;
    }

    public Bar withTwo(String two) {
      return new Bar(one, two);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (obj == null) return false;
      if (this.getClass() != obj.getClass()) return false;
      Bar other = (Bar) obj;
      if (!Objects.equals(this.one, other.one)) return false;
      if (!Objects.equals(this.two, other.two)) return false;
      return true;
    }

    @Override
    public int hashCode() {
      int result = 1;
      result = 31 * result + Objects.hashCode(this.one);
      result = 31 * result + Objects.hashCode(this.two);
      return result;
    }

    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder(150);
      builder.append(Bar.class.getSimpleName()).append(" {");
      appendProperty(builder, "one", this.one);
      appendProperty(builder, "two", this.two);
      builder.append("\n}");
      return builder.toString();
    }
  }

  public static final class Baz extends Bar {
    private final @NonNull Duration three;

    public Baz(@Named("one") long one, @Named("two") String two,
        @Named("three") @NonNull Duration three) {
      super(one, two);
      this.three = three;
    }

    public Baz withOne(long one) {
      return new Baz(one, two, three);
    }

    public Baz withTwo(String two) {
      return new Baz(one, two, three);
    }

    public @NonNull Duration getThree() {
      return three;
    }

    public Baz withThree(@NonNull Duration three) {
      return new Baz(one, two, three);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (obj == null) return false;
      if (this.getClass() != obj.getClass()) return false;
      Baz other = (Baz) obj;
      if (!Objects.equals(this.one, other.one)) return false;
      if (!Objects.equals(this.two, other.two)) return false;
      if (!Objects.equals(this.three, other.three)) return false;
      return true;
    }

    @Override
    public int hashCode() {
      int result = 1;
      result = 31 * result + Objects.hashCode(this.one);
      result = 31 * result + Objects.hashCode(this.two);
      result = 31 * result + Objects.hashCode(this.three);
      return result;
    }

    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder(200);
      builder.append(Baz.class.getSimpleName()).append(" {");
      appendProperty(builder, "one", this.one);
      appendProperty(builder, "two", this.two);
      appendProperty(builder, "three", this.three);
      builder.append("\n}");
      return builder.toString();
    }
  }
}
