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

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

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

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

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

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

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

  return 0;
}