// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --harmony-private-methods

"use strict";

// Basic private method test
{
  let calledWith;
  class C {
    #a(arg) { calledWith = arg; }
    callA(arg) { this.#a(arg); }
  }

  const c = new C;
  assertEquals(undefined, c.a);
  assertEquals(undefined, calledWith);
  c.callA(1);
  assertEquals(1, calledWith);
}

// Call private method in another instance
{
  class C {
    #a(arg) { this.calledWith = arg; }
    callAIn(obj, arg) { obj.#a(arg); }
  }

  const c = new C;
  const c2 = new C;

  assertEquals(undefined, c.a);
  assertEquals(undefined, c.calledWith);
  assertEquals(undefined, c2.calledWith);

  c2.callAIn(c, 'fromC2');
  assertEquals('fromC2', c.calledWith);
  assertEquals(undefined, c2.calledWith);

  c2.callAIn(c2, 'c2');
  assertEquals('fromC2', c.calledWith);
  assertEquals('c2', c2.calledWith);

  assertThrows(() => { c2.callAIn({}); }, TypeError);
}

// Private methods and private fields
{
  class C {
    #a;
    constructor(a) {
      this.#a = a;
    }
    #getAPlus1() {
      return this.#a + 1;
    }
    equals(obj) {
      return this.#getAPlus1() === obj.#getAPlus1();
    }
  }
  const c = new C(0);
  const c2 = new C(2);
  const c3 = new C(2);
  assertEquals(true, c2.equals(c3));
  assertEquals(false, c2.equals(c));
  assertEquals(false, c3.equals(c));
}

// Class inheritance
{
  class A {
    #val;
    constructor(a) {
      this.#val = a;
    }
    #a() { return this.#val; }
    getA() { return this.#a(); }
  }
  class B extends A {
    constructor(b) {
      super(b);
    }
    b() { return this.getA() }
  }
  const b = new B(1);
  assertEquals(1, b.b());
}

// Private members should be accessed according to the class the
// invoked method is in.
{
  class A {
    #val;
    constructor(a) {
      this.#val = a;
    }
    #getVal() { return this.#val; }
    getA() { return this.#getVal(); }
    getVal() { return this.#getVal(); }
  }

  class B extends A {
    #val;
    constructor(a, b) {
      super(a);
      this.#val = b;
    }
    #getVal() { return this.#val; }
    getB() { return this.#getVal(); }
    getVal() { return this.#getVal(); }
  }

  const b = new B(1, 2);
  assertEquals(1, b.getA());
  assertEquals(2, b.getB());
  assertEquals(1, A.prototype.getVal.call(b));
  assertEquals(2, B.prototype.getVal.call(b));
  const a = new A(1);
  assertEquals(1, a.getA());
  assertThrows(() => B.prototype.getB.call(a), TypeError);
}

// Private methods in nested classes.
{
  class C {
    #b() {
      class B {
        #foo(arg) { return arg; }
        callFoo(arg) { return this.#foo(arg); }
      }
      return new B();
    }
    createB() { return this.#b(); }
  }
  const c = new C;
  const b = c.createB();
  assertEquals(1, b.callFoo(1));
}

// Private methods in nested classes with inheritance.
{
  class C {
    #b() {
      class B extends C {
        #foo(arg) { return arg; }
        callFoo(arg) { return this.#foo(arg); }
      }
      return new B();
    }
    createB() { return this.#b(); }
  }

  const c = new C;
  const b = c.createB();
  assertEquals(1, b.callFoo(1));
  const b2 = b.createB();
  assertEquals(1, b2.callFoo(1));
}

// Class expressions.
{
  const C = class {
    #a() { return 1; }
    callA(obj) { return obj.#a() }
  };
  const c = new C;
  const c2 = new C;
  assertEquals(1, c.callA(c));
  assertEquals(1, c.callA(c2));
}

// Nested class expressions.
{
  const C = class {
    #b() {
      const B = class {
        #foo(arg) { return arg; }
        callFoo(arg) { return this.#foo(arg); }
      };
      return new B();
    }
    createB() { return this.#b(); }
  };

  const c = new C;
  const b = c.createB();
  assertEquals(1, b.callFoo(1));
}


// Nested class expressions with hierarchy.
{
  const C = class {
    #b() {
      const B = class extends C {
        #foo(arg) { return arg; }
        callFoo(arg) { return this.#foo(arg); }
      }
      return new B();
    }
    createB() { return this.#b(); }
  }

  const c = new C;
  const b = c.createB();
  assertEquals(1, b.callFoo(1));
  const b2 = b.createB();
  assertEquals(1, b2.callFoo(1));
}

// Adding the brand twice on the same object should throw.
{
  class A {
    constructor(arg) {
      return arg;
    }
  }

  class C extends A {
    #x() { }

    constructor(arg) {
      super(arg);
    }
  }

  let c1 = new C({});
  assertThrows(() => new C(c1), TypeError);
}

// Private methods should be not visible to proxies.
{
  class X {
    #x() {}
    x() { this.#x(); };
    callX(obj) { obj.#x(); }
  }
  let handlerCalled = false;
  const x = new X();
  let p = new Proxy(new X, {
    apply(target, thisArg, argumentsList) {
      handlerCalled = true;
      Reflect.apply(target, thisArg, argumentsList);
    }
  });
  assertThrows(() => p.x(), TypeError);
  assertThrows(() => x.callX(p), TypeError);
  assertThrows(() => X.prototype.x.call(p), TypeError);
  assertThrows(() => X.prototype.callX(p), TypeError);
  assertEquals(false, handlerCalled);
}

// Reference outside of class.
{
  class C {
    #a() {}
  }
  assertThrows('new C().#a()');
}

// Duplicate private names.
{
  assertThrows('class C { #a = 1; #a() {} }');
}

{
  // TODO(v8:9177): test extending a class expression that does not have
  // a private method.
  class D extends class {
    #c() {}
  } {
    #d() {}
  }

  class E extends D {
    #e() {}
  }

  new D;
  new E;
}
