// Copyright (C) 2009 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.server.contact;

import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.errors.ContactInformationStoreException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.reviewdb.client.ContactInformation;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.UrlEncoded;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.ProvisionException;
import com.google.inject.Singleton;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.bc.BcPGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;

/** Encrypts {@link ContactInformation} instances and saves them. */
@Singleton
class EncryptedContactStore implements ContactStore {
  private static final Logger log =
      LoggerFactory.getLogger(EncryptedContactStore.class);
  private static final TimeZone UTC = TimeZone.getTimeZone("UTC");

  private final SchemaFactory<ReviewDb> schema;
  private final PGPPublicKey dest;
  private final SecureRandom prng;
  private final URL storeUrl;
  private final String storeAPPSEC;
  private final ContactStoreConnection.Factory connFactory;

  EncryptedContactStore(final URL storeUrl, final String storeAPPSEC,
      final File pubKey, final SchemaFactory<ReviewDb> schema,
      final ContactStoreConnection.Factory connFactory) {
    this.storeUrl = storeUrl;
    this.storeAPPSEC = storeAPPSEC;
    this.schema = schema;
    this.dest = selectKey(readPubRing(pubKey));
    this.connFactory = connFactory;

    final String prngName = "SHA1PRNG";
    try {
      prng = SecureRandom.getInstance(prngName);
    } catch (NoSuchAlgorithmException e) {
      throw new ProvisionException("Cannot create " + prngName, e);
    }

    // Run a test encryption to verify the proper algorithms exist in
    // our JVM and we are able to invoke them. This helps to identify
    // a system configuration problem early at startup, rather than a
    // lot later during runtime.
    //
    try {
      encrypt("test", new Date(0), "test".getBytes("UTF-8"));
    } catch (PGPException | IOException e) {
      throw new ProvisionException("PGP encryption not available", e);
    }
  }

  @Override
  public boolean isEnabled() {
    return true;
  }

  private static PGPPublicKeyRingCollection readPubRing(final File pub) {
    try (InputStream fin = new FileInputStream(pub);
        InputStream in = PGPUtil.getDecoderStream(fin)) {
        return new BcPGPPublicKeyRingCollection(in);
    } catch (IOException | PGPException e) {
      throw new ProvisionException("Cannot read " + pub, e);
    }
  }

  private static PGPPublicKey selectKey(final PGPPublicKeyRingCollection rings) {
    for (final Iterator<?> ri = rings.getKeyRings(); ri.hasNext();) {
      final PGPPublicKeyRing currRing = (PGPPublicKeyRing) ri.next();
      for (final Iterator<?> ki = currRing.getPublicKeys(); ki.hasNext();) {
        final PGPPublicKey k = (PGPPublicKey) ki.next();
        if (k.isEncryptionKey()) {
          return k;
        }
      }
    }
    return null;
  }

  @Override
  public void store(final Account account, final ContactInformation info)
      throws ContactInformationStoreException {
    try {
      final byte[] plainText = format(account, info).getBytes("UTF-8");
      final String fileName = "account-" + account.getId();
      final Date fileDate = account.getContactFiledOn();
      final byte[] encText = encrypt(fileName, fileDate, plainText);
      final String encStr = new String(encText, "UTF-8");

      final Timestamp filedOn = account.getContactFiledOn();
      final UrlEncoded u = new UrlEncoded();
      if (storeAPPSEC != null) {
        u.put("APPSEC", storeAPPSEC);
      }
      if (account.getPreferredEmail() != null) {
        u.put("email", account.getPreferredEmail());
      }
      if (filedOn != null) {
        u.put("filed", String.valueOf(filedOn.getTime() / 1000L));
      }
      u.put("account_id", String.valueOf(account.getId().get()));
      u.put("data", encStr);
      connFactory.open(storeUrl).store(u.toString().getBytes("UTF-8"));
    } catch (IOException | PGPException e) {
      log.error("Cannot store encrypted contact information", e);
      throw new ContactInformationStoreException(e);
    }
  }

  private final PGPEncryptedDataGenerator cpk() {
    final BcPGPDataEncryptorBuilder builder =
        new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5)
            .setSecureRandom(prng);
    PGPEncryptedDataGenerator cpk =
        new PGPEncryptedDataGenerator(builder, true);
    final BcPublicKeyKeyEncryptionMethodGenerator methodGenerator =
        new BcPublicKeyKeyEncryptionMethodGenerator(dest);
    cpk.addMethod(methodGenerator);
    return cpk;
  }

  private byte[] encrypt(final String name, final Date date,
      final byte[] rawText) throws PGPException,
      IOException {
    final byte[] zText = compress(name, date, rawText);

    final ByteArrayOutputStream buf = new ByteArrayOutputStream();
    final ArmoredOutputStream aout = new ArmoredOutputStream(buf);
    final OutputStream cout = cpk().open(aout, zText.length);
    cout.write(zText);
    cout.close();
    aout.close();

    return buf.toByteArray();
  }

  private static byte[] compress(final String fileName, Date fileDate,
      final byte[] plainText) throws IOException {
    final ByteArrayOutputStream buf = new ByteArrayOutputStream();
    final PGPCompressedDataGenerator comdg;
    final int len = plainText.length;
    if (fileDate == null) {
      fileDate = PGPLiteralData.NOW;
    }

    comdg = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
    final OutputStream out =
        new PGPLiteralDataGenerator().open(comdg.open(buf),
            PGPLiteralData.BINARY, fileName, len, fileDate);
    out.write(plainText);
    out.close();
    comdg.close();
    return buf.toByteArray();
  }

  private String format(final Account account, final ContactInformation info)
      throws ContactInformationStoreException {
    Timestamp on = account.getContactFiledOn();
    if (on == null) {
      on = TimeUtil.nowTs();
    }

    final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    df.setTimeZone(UTC);

    final StringBuilder b = new StringBuilder();
    field(b, "Account-Id", account.getId().toString());
    field(b, "Date", df.format(on) + " " + UTC.getID());
    field(b, "Full-Name", account.getFullName());
    field(b, "Preferred-Email", account.getPreferredEmail());

    try {
      final ReviewDb db = schema.open();
      try {
        for (final AccountExternalId e : db.accountExternalIds().byAccount(
            account.getId())) {
          final StringBuilder oistr = new StringBuilder();
          if (e.getEmailAddress() != null && e.getEmailAddress().length() > 0) {
            if (oistr.length() > 0) {
              oistr.append(' ');
            }
            oistr.append(e.getEmailAddress());
          }
          if (e.isScheme(AccountExternalId.SCHEME_MAILTO)) {
            if (oistr.length() > 0) {
              oistr.append(' ');
            }
            oistr.append('<');
            oistr.append(e.getExternalId());
            oistr.append('>');
          }
          field(b, "Identity", oistr.toString());
        }
      } finally {
        db.close();
      }
    } catch (OrmException e) {
      throw new ContactInformationStoreException(e);
    }

    field(b, "Address", info.getAddress());
    field(b, "Country", info.getCountry());
    field(b, "Phone-Number", info.getPhoneNumber());
    field(b, "Fax-Number", info.getFaxNumber());
    return b.toString();
  }

  private static void field(final StringBuilder b, final String name,
      String value) {
    if (value == null) {
      return;
    }
    value = value.trim();
    if (value.length() == 0) {
      return;
    }

    b.append(name);
    b.append(':');
    if (value.indexOf('\n') == -1) {
      b.append(' ');
      b.append(value);
    } else {
      value = value.replaceAll("\r\n", "\n");
      value = value.replaceAll("\n", "\n\t");
      b.append("\n\t");
      b.append(value);
    }
    b.append('\n');
  }
}
