// 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;

import com.google.gerrit.client.reviewdb.Account;
import com.google.gerrit.client.reviewdb.AccountExternalId;
import com.google.gerrit.client.reviewdb.ContactInformation;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.client.rpc.ContactInformationStoreException;
import com.google.gwtjsonrpc.server.XsrfException;
import com.google.gwtorm.client.OrmException;

import org.apache.sshd.common.util.SecurityUtils;
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.mortbay.util.UrlEncoded;
import org.spearce.jgit.util.NB;

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.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
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. */
public class EncryptedContactStore {
  private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
  private static boolean inited;
  private static EncryptedContactStore self;

  private static synchronized EncryptedContactStore getInstance()
      throws ContactInformationStoreException {
    if (!inited) {
      inited = true;
      self = new EncryptedContactStore();
    }
    if (self == null) {
      throw new ContactInformationStoreException();
    }
    return self;
  }

  public static void store(final Account account, final ContactInformation info)
      throws ContactInformationStoreException {
    getInstance().storeImpl(account, info);
  }

  private PGPPublicKey dest;
  private SecureRandom prng;
  private URL storeUrl;
  private String storeAPPSEC;

  private EncryptedContactStore() throws ContactInformationStoreException {
    final GerritServer gs;
    try {
      gs = GerritServer.getInstance();
    } catch (OrmException e) {
      throw new ContactInformationStoreException(e);
    } catch (XsrfException e) {
      throw new ContactInformationStoreException(e);
    }

    if (gs.getContactStoreURL() == null) {
      throw new ContactInformationStoreException(new IllegalStateException(
          "No contactStoreURL configured"));
    }
    try {
      storeUrl = new URL(gs.getContactStoreURL());
    } catch (MalformedURLException e) {
      throw new ContactInformationStoreException(e);
    }
    storeAPPSEC = gs.getContactStoreAPPSEC();

    if (!SecurityUtils.isBouncyCastleRegistered()) {
      throw new ContactInformationStoreException(new NoSuchProviderException(
          "BC (aka BouncyCastle)"));
    }

    try {
      prng = SecureRandom.getInstance("SHA1PRNG");
    } catch (NoSuchAlgorithmException e) {
      throw new ContactInformationStoreException(e);
    }

    dest = selectKey(readPubRing(gs));
  }

  private PGPPublicKeyRingCollection readPubRing(final GerritServer gs)
      throws ContactInformationStoreException {
    final File pub = new File(gs.getSitePath(), "contact_information.pub");
    try {
      InputStream in = new FileInputStream(pub);
      try {
        in = PGPUtil.getDecoderStream(in);
        return new PGPPublicKeyRingCollection(in);
      } finally {
        in.close();
      }
    } catch (IOException e) {
      throw new ContactInformationStoreException(e);
    } catch (PGPException e) {
      throw new ContactInformationStoreException(e);
    }
  }

  private 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;
  }

  private void storeImpl(final Account account, final ContactInformation info)
      throws ContactInformationStoreException {
    try {
      final byte[] plainText = format(account, info).getBytes("UTF-8");
      final byte[] encText = encrypt(dest, compress(account, plainText));
      final String encStr = new String(encText, "UTF-8");

      final Timestamp filedOn = account.getContactFiledOn();
      final UrlEncoded u = new UrlEncoded();
      if (storeAPPSEC != null) {
        u.add("APPSEC", storeAPPSEC);
      }
      if (account.getPreferredEmail() != null) {
        u.add("email", account.getPreferredEmail());
      }
      if (filedOn != null) {
        u.add("filed", String.valueOf(filedOn.getTime() / 1000L));
      }
      u.add("account_id", String.valueOf(account.getId().get()));
      u.add("data", encStr);
      final byte[] body = u.encode().getBytes("UTF-8");

      final HttpURLConnection c = (HttpURLConnection) storeUrl.openConnection();
      c.setRequestMethod("POST");
      c.setRequestProperty("Content-Type",
          "application/x-www-form-urlencoded; charset=UTF-8");
      c.setDoOutput(true);
      c.setFixedLengthStreamingMode(body.length);
      final OutputStream out = c.getOutputStream();
      out.write(body);
      out.close();

      if (c.getResponseCode() == 200) {
        final byte[] dst = new byte[2];
        final InputStream in = c.getInputStream();
        try {
          NB.readFully(in, dst, 0, 2);
        } finally {
          in.close();
        }
        if (dst[0] != 'O' || dst[1] != 'K') {
          throw new IOException("Store failed: " + c.getResponseCode());
        }
      } else {
        throw new IOException("Store failed: " + c.getResponseCode());
      }

    } catch (IOException e) {
      throw new ContactInformationStoreException(e);
    } catch (PGPException e) {
      throw new ContactInformationStoreException(e);
    } catch (NoSuchProviderException e) {
      throw new ContactInformationStoreException(e);
    }
  }

  private byte[] encrypt(final PGPPublicKey dst, final byte[] zText)
      throws NoSuchProviderException, PGPException, IOException {
    final PGPEncryptedDataGenerator cpk =
        new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, true, prng, "BC");
    cpk.addMethod(dst);

    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 Account account, final byte[] plainText)
      throws IOException {
    final ByteArrayOutputStream buf = new ByteArrayOutputStream();
    final PGPCompressedDataGenerator comdg;
    final String name = "account-" + account.getId();
    final int len = plainText.length;
    Date date = account.getContactFiledOn();
    if (date == null) {
      date = PGPLiteralData.NOW;
    }

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

  private static String format(final Account account,
      final ContactInformation info) throws ContactInformationStoreException {
    Timestamp on = account.getContactFiledOn();
    if (on == null) {
      on = new Timestamp(System.currentTimeMillis());
    }

    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 = Common.getSchemaFactory().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.getExternalId() != null && e.getExternalId().length() > 0
              && !e.getExternalId().startsWith("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');
  }
}
