// Copyright (C) 2015 The Android Open Source Project
//
// 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.gerrit.gpg;

import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString;
import static com.google.gerrit.gpg.PublicKeyStore.keyObjectId;
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.google.gerrit.gpg.testutil.TestKey;
import com.google.gerrit.reviewdb.client.RefNames;

import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class PublicKeyStoreTest {
  private TestRepository<?> tr;
  private PublicKeyStore store;

  @Before
  public void setUp() throws Exception {
    tr = new TestRepository<>(new InMemoryRepository(
        new DfsRepositoryDescription("pubkeys")));
    store = new PublicKeyStore(tr.getRepository());
  }

  @Test
  public void testKeyIdToString() throws Exception {
    PGPPublicKey key = TestKey.key1().getPublicKey();
    assertEquals("46328A8C", keyIdToString(key.getKeyID()));
  }

  @Test
  public void testKeyToString() throws Exception {
    PGPPublicKey key = TestKey.key1().getPublicKey();
    assertEquals("46328A8C Testuser One <test1@example.com>"
          + " (04AE A7ED 2F82 1133 E5B1  28D1 ED06 25DC 4632 8A8C)",
        keyToString(key));
  }

  @Test
  public void testKeyObjectId() throws Exception {
    PGPPublicKey key = TestKey.key1().getPublicKey();
    String objId = keyObjectId(key.getKeyID()).name();
    assertEquals("ed0625dc46328a8c000000000000000000000000", objId);
    assertEquals(keyIdToString(key.getKeyID()).toLowerCase(),
        objId.substring(8, 16));
  }

  @Test
  public void testGet() throws Exception {
    TestKey key1 = TestKey.key1();
    tr.branch(RefNames.REFS_GPG_KEYS)
        .commit()
        .add(keyObjectId(key1.getKeyId()).name(),
          key1.getPublicKeyArmored())
        .create();
    TestKey key2 = TestKey.key2();
    tr.branch(RefNames.REFS_GPG_KEYS)
        .commit()
        .add(keyObjectId(key2.getKeyId()).name(),
          key2.getPublicKeyArmored())
        .create();

    assertKeys(key1.getKeyId(), key1);
    assertKeys(key2.getKeyId(), key2);
  }

  @Test
  public void testGetMultiple() throws Exception {
    TestKey key1 = TestKey.key1();
    TestKey key2 = TestKey.key2();
    tr.branch(RefNames.REFS_GPG_KEYS)
        .commit()
        .add(keyObjectId(key1.getKeyId()).name(),
            key1.getPublicKeyArmored()
              // Mismatched for this key ID, but we can still read it out.
              + key2.getPublicKeyArmored())
        .create();
    assertKeys(key1.getKeyId(), key1, key2);
  }

  @Test
  public void save() throws Exception {
    TestKey key1 = TestKey.key1();
    TestKey key2 = TestKey.key2();
    store.add(key1.getPublicKeyRing());
    store.add(key2.getPublicKeyRing());

    assertEquals(RefUpdate.Result.NEW, store.save(newCommitBuilder()));

    assertKeys(key1.getKeyId(), key1);
    assertKeys(key2.getKeyId(), key2);
  }

  @Test
  public void saveAppendsToExistingList() throws Exception {
    TestKey key1 = TestKey.key1();
    TestKey key2 = TestKey.key2();
    tr.branch(RefNames.REFS_GPG_KEYS)
        .commit()
        // Mismatched for this key ID, but we can still read it out.
        .add(keyObjectId(key1.getKeyId()).name(), key2.getPublicKeyArmored())
        .create();

    store.add(key1.getPublicKeyRing());
    assertEquals(RefUpdate.Result.FAST_FORWARD, store.save(newCommitBuilder()));

    assertKeys(key1.getKeyId(), key1, key2);

    try (ObjectReader reader = tr.getRepository().newObjectReader();
        RevWalk rw = new RevWalk(reader)) {
      NoteMap notes = NoteMap.read(
          reader, tr.getRevWalk().parseCommit(
            tr.getRepository().getRef(RefNames.REFS_GPG_KEYS).getObjectId()));
      String contents = new String(
          reader.open(notes.get(keyObjectId(key1.getKeyId()))).getBytes(),
          UTF_8);
      String header = "-----BEGIN PGP PUBLIC KEY BLOCK-----";
      int i1 = contents.indexOf(header);
      assertTrue(i1 >= 0);
      int i2 = contents.indexOf(header, i1 + header.length());
      assertTrue(i2 >= 0);
    }
  }

  @Test
  public void updateExisting() throws Exception {
    TestKey key5 = TestKey.key5();
    PGPPublicKeyRing keyRing = key5.getPublicKeyRing();
    PGPPublicKey key = keyRing.getPublicKey();
    store.add(keyRing);
    assertEquals(RefUpdate.Result.NEW, store.save(newCommitBuilder()));

    assertUserIds(store.get(key5.getKeyId()).iterator().next(),
        "Testuser Five <test5@example.com>",
        "foo:myId");

    keyRing = PGPPublicKeyRing.removePublicKey(keyRing, key);
    key = PGPPublicKey.removeCertification(key, "foo:myId");
    keyRing = PGPPublicKeyRing.insertPublicKey(keyRing, key);
    store.add(keyRing);
    assertEquals(RefUpdate.Result.FAST_FORWARD, store.save(newCommitBuilder()));

    Iterator<PGPPublicKeyRing> keyRings = store.get(key.getKeyID()).iterator();
    keyRing = keyRings.next();
    assertFalse(keyRings.hasNext());
    assertUserIds(keyRing, "Testuser Five <test5@example.com>");
  }

  @Test
  public void remove() throws Exception {
    TestKey key1 = TestKey.key1();
    store.add(key1.getPublicKeyRing());
    assertEquals(RefUpdate.Result.NEW, store.save(newCommitBuilder()));
    assertKeys(key1.getKeyId(), key1);

    store.remove(key1.getPublicKey().getFingerprint());
    assertEquals(RefUpdate.Result.FAST_FORWARD, store.save(newCommitBuilder()));
    assertKeys(key1.getKeyId());
  }

  @Test
  public void removeNonexisting() throws Exception {
    TestKey key1 = TestKey.key1();
    store.add(key1.getPublicKeyRing());
    assertEquals(RefUpdate.Result.NEW, store.save(newCommitBuilder()));

    TestKey key2 = TestKey.key2();
    store.remove(key2.getPublicKey().getFingerprint());
    assertEquals(RefUpdate.Result.NO_CHANGE, store.save(newCommitBuilder()));
    assertKeys(key1.getKeyId(), key1);
  }

  @Test
  public void addThenRemove() throws Exception {
    TestKey key1 = TestKey.key1();
    store.add(key1.getPublicKeyRing());
    store.remove(key1.getPublicKey().getFingerprint());
    assertEquals(RefUpdate.Result.NO_CHANGE, store.save(newCommitBuilder()));
    assertKeys(key1.getKeyId());
  }

  private void assertKeys(long keyId, TestKey... expected)
      throws Exception {
    Set<String> expectedStrings = new TreeSet<>();
    for (TestKey k : expected) {
      expectedStrings.add(keyToString(k.getPublicKey()));
    }
    PGPPublicKeyRingCollection actual = store.get(keyId);
    Set<String> actualStrings = new TreeSet<>();
    for (PGPPublicKeyRing k : actual) {
      actualStrings.add(keyToString(k.getPublicKey()));
    }
    assertEquals(expectedStrings, actualStrings);
  }

  private void assertUserIds(PGPPublicKeyRing keyRing, String... expected)
      throws Exception {
    List<String> actual = new ArrayList<>();
    @SuppressWarnings("unchecked")
    Iterator<String> userIds = store.get(keyRing.getPublicKey().getKeyID())
        .iterator().next().getPublicKey().getUserIDs();
    while (userIds.hasNext()) {
      actual.add(userIds.next());
    }

    assertEquals(actual, Arrays.asList(expected));
  }

  private CommitBuilder newCommitBuilder() {
    CommitBuilder cb = new CommitBuilder();
    PersonIdent ident = new PersonIdent("A U Thor", "author@example.com");
    cb.setAuthor(ident);
    cb.setCommitter(ident);
    return cb;
  }
}
