/*
 * Copyright (C) 2019 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.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <string>

#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <openssl/crypto.h>
#include <selinux/android.h>
#include <selinux/label.h>
#include <selinux/selinux.h>

#include "edify/expr.h"
#include "updater/blockimg.h"
#include "updater/dynamic_partitions.h"
#include "updater/install.h"
#include "updater/updater.h"
#include "updater/updater_runtime.h"

// Generated by the makefile, this function defines the
// RegisterDeviceExtensions() function, which calls all the
// registration functions for device-specific extensions.
#include "register.inc"

static void UpdaterLogger(android::base::LogId /* id */, android::base::LogSeverity /* severity */,
                          const char* /* tag */, const char* /* file */, unsigned int /* line */,
                          const char* message) {
  fprintf(stdout, "%s\n", message);
}

int main(int argc, char** argv) {
  // Various things log information to stdout or stderr more or less
  // at random (though we've tried to standardize on stdout).  The
  // log file makes more sense if buffering is turned off so things
  // appear in the right order.
  setbuf(stdout, nullptr);
  setbuf(stderr, nullptr);

  // We don't have logcat yet under recovery. Update logs will always be written to stdout
  // (which is redirected to recovery.log).
  android::base::InitLogging(argv, &UpdaterLogger);

  // Run the libcrypto KAT(known answer tests) based self tests.
  if (BORINGSSL_self_test() != 1) {
    LOG(ERROR) << "Failed to run the boringssl self tests";
    return EXIT_FAILURE;
  }

  if (argc != 4 && argc != 5) {
    LOG(ERROR) << "unexpected number of arguments: " << argc;
    return EXIT_FAILURE;
  }

  char* version = argv[1];
  if ((version[0] != '1' && version[0] != '2' && version[0] != '3') || version[1] != '\0') {
    // We support version 1, 2, or 3.
    LOG(ERROR) << "wrong updater binary API; expected 1, 2, or 3; got " << argv[1];
    return EXIT_FAILURE;
  }

  int fd;
  if (!android::base::ParseInt(argv[2], &fd)) {
    LOG(ERROR) << "Failed to parse fd in " << argv[2];
    return EXIT_FAILURE;
  }

  std::string package_name = argv[3];

  bool is_retry = false;
  if (argc == 5) {
    if (strcmp(argv[4], "retry") == 0) {
      is_retry = true;
    } else {
      LOG(ERROR) << "unexpected argument: " << argv[4];
      return EXIT_FAILURE;
    }
  }

  // Configure edify's functions.
  RegisterBuiltins();
  RegisterInstallFunctions();
  RegisterBlockImageFunctions();
  RegisterDynamicPartitionsFunctions();
  RegisterDeviceExtensions();

  auto sehandle = selinux_android_file_context_handle();
  selinux_android_set_sehandle(sehandle);

  Updater updater(std::make_unique<UpdaterRuntime>(sehandle));
  if (!updater.Init(fd, package_name, is_retry)) {
    return EXIT_FAILURE;
  }

  if (!updater.RunUpdate()) {
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}