// Copyright (C) 2017 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.googlesource.gerrit.plugins.lfs;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import java.time.Instant;
import java.util.List;
import java.util.Optional;

public abstract class LfsAuthToken {
  public abstract static class Processor<T extends LfsAuthToken> {
    private static final char DELIMETER = '~';

    protected final LfsCipher cipher;

    protected Processor(LfsCipher cipher) {
      this.cipher = cipher;
    }

    public String serialize(T token) {
      return cipher.encrypt(Joiner.on(DELIMETER).join(getValues(token)));
    }

    public Optional<T> deserialize(String input) {
      Optional<String> decrypted = cipher.decrypt(input);
      if (!decrypted.isPresent()) {
        return Optional.empty();
      }

      return createToken(Splitter.on(DELIMETER).splitToList(decrypted.get()));
    }

    protected abstract List<String> getValues(T token);

    protected abstract Optional<T> createToken(List<String> values);
  }

  public abstract static class Verifier<T extends LfsAuthToken> {
    protected final T token;

    protected Verifier(T token) {
      this.token = token;
    }

    public boolean verify() {
      return onTime(Instant.now()) && verifyTokenValues();
    }

    protected abstract boolean verifyTokenValues();

    public boolean onTime(Instant when) {
      return when.isBefore(token.issued.plusSeconds(token.expiresIn));
    }
  }

  public final Instant issued;
  public final Long expiresIn;

  protected LfsAuthToken(Instant issued, Long expiresIn) {
    this.issued = issued;
    this.expiresIn = expiresIn;
  }

  protected LfsAuthToken(String issued, Long expiresIn) {
    this.issued = Instant.parse(issued);
    this.expiresIn = expiresIn;
  }
}
