//
// Copyright (C) 2014 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 <sysexits.h>

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/command_line.h>
#include <base/threading/thread.h>
#include <brillo/minijail/minijail.h>
#include <brillo/syslog_logging.h>
#include <brillo/userdb_utils.h>

#include "trunks/background_command_transceiver.h"
#include "trunks/resource_manager.h"
#include "trunks/tpm_handle.h"
#include "trunks/tpm_simulator_handle.h"
#if defined(USE_BINDER_IPC)
#include "trunks/trunks_binder_service.h"
#else
#include "trunks/trunks_dbus_service.h"
#endif
#include "trunks/trunks_factory_impl.h"
#include "trunks/trunks_ftdi_spi.h"

namespace {

const uid_t kRootUID = 0;
const char kTrunksUser[] = "trunks";
const char kTrunksGroup[] = "trunks";
#if defined(__ANDROID__)
const char kTrunksSeccompPath[] =
    "/system/usr/share/policy/trunksd-seccomp.policy";
#else
const char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy";
#endif
const char kBackgroundThreadName[] = "trunksd_background_thread";

void InitMinijailSandbox() {
  uid_t trunks_uid;
  gid_t trunks_gid;
  CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid))
      << "Error getting trunks uid and gid.";
  CHECK_EQ(getuid(), kRootUID) << "trunksd not initialized as root.";
  brillo::Minijail* minijail = brillo::Minijail::GetInstance();
  struct minijail* jail = minijail->New();
  minijail->DropRoot(jail, kTrunksUser, kTrunksGroup);
  minijail->UseSeccompFilter(jail, kTrunksSeccompPath);
  minijail->Enter(jail);
  minijail->Destroy(jail);
  CHECK_EQ(getuid(), trunks_uid)
      << "trunksd was not able to drop user privilege.";
  CHECK_EQ(getgid(), trunks_gid)
      << "trunksd was not able to drop group privilege.";
}

}  // namespace

int main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  int flags = brillo::kLogToSyslog;
  if (cl->HasSwitch("log_to_stderr")) {
    flags |= brillo::kLogToStderr;
  }
  brillo::InitLog(flags);

// Create a service instance before anything else so objects like
// AtExitManager exist.
#if defined(USE_BINDER_IPC)
  trunks::TrunksBinderService service;
#else
  trunks::TrunksDBusService service;
#endif

  // Chain together command transceivers:
  //   [IPC] --> BackgroundCommandTransceiver
  //         --> ResourceManager
  //         --> TpmHandle
  //         --> [TPM]
  trunks::CommandTransceiver* low_level_transceiver;
  if (cl->HasSwitch("ftdi")) {
    LOG(INFO) << "Sending commands to FTDI SPI.";
    low_level_transceiver = new trunks::TrunksFtdiSpi();
  } else if (cl->HasSwitch("simulator")) {
    LOG(INFO) << "Sending commands to simulator.";
    low_level_transceiver = new trunks::TpmSimulatorHandle();
  } else {
    low_level_transceiver = new trunks::TpmHandle();
  }
  CHECK(low_level_transceiver->Init())
      << "Error initializing TPM communication.";
  // This needs to be *after* opening the TPM handle and *before* starting the
  // background thread.
  InitMinijailSandbox();
  base::Thread background_thread(kBackgroundThreadName);
  CHECK(background_thread.Start()) << "Failed to start background thread.";
  trunks::TrunksFactoryImpl factory(low_level_transceiver);
  CHECK(factory.Initialize()) << "Failed to initialize trunks factory.";
  trunks::ResourceManager resource_manager(factory, low_level_transceiver);
  background_thread.task_runner()->PostNonNestableTask(
      FROM_HERE, base::Bind(&trunks::ResourceManager::Initialize,
                            base::Unretained(&resource_manager)));
  trunks::BackgroundCommandTransceiver background_transceiver(
      &resource_manager, background_thread.task_runner());
  service.set_transceiver(&background_transceiver);
  LOG(INFO) << "Trunks service started.";
  return service.Run();
}
