/*
 * Copyright (C) 2016 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.
 *
 * Main driver of the dexlayout utility.
 *
 * This is a tool to read dex files into an internal representation,
 * reorganize the representation, and emit dex files with a better
 * file layout.
 */

#include "dexlayout.h"

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "base/logging.h"
#include "jit/offline_profiling_info.h"
#include "runtime.h"
#include "mem_map.h"

namespace art {

static const char* kProgramName = "dexlayout";

/*
 * Shows usage.
 */
static void Usage(void) {
  fprintf(stderr, "Copyright (C) 2016 The Android Open Source Project\n\n");
  fprintf(stderr, "%s: [-a] [-c] [-d] [-e] [-f] [-h] [-i] [-l layout] [-o outfile] [-p profile]"
                  " [-s] [-w directory] dexfile...\n\n", kProgramName);
  fprintf(stderr, " -a : display annotations\n");
  fprintf(stderr, " -b : build dex_ir\n");
  fprintf(stderr, " -c : verify checksum and exit\n");
  fprintf(stderr, " -d : disassemble code sections\n");
  fprintf(stderr, " -e : display exported items only\n");
  fprintf(stderr, " -f : display summary information from file header\n");
  fprintf(stderr, " -h : display file header details\n");
  fprintf(stderr, " -i : ignore checksum failures\n");
  fprintf(stderr, " -l : output layout, either 'plain' or 'xml'\n");
  fprintf(stderr, " -o : output file name (defaults to stdout)\n");
  fprintf(stderr, " -p : profile file name (defaults to no profile)\n");
  fprintf(stderr, " -s : visualize reference pattern\n");
  fprintf(stderr, " -w : output dex directory \n");
}

/*
 * Main driver of the dexlayout utility.
 */
int DexlayoutDriver(int argc, char** argv) {
  // Art specific set up.
  InitLogging(argv, Runtime::Aborter);
  MemMap::Init();

  Options options;
  options.dump_ = true;
  options.verbose_ = true;
  bool want_usage = false;

  // Parse all arguments.
  while (1) {
    const int ic = getopt(argc, argv, "abcdefghil:mo:p:sw:");
    if (ic < 0) {
      break;  // done
    }
    switch (ic) {
      case 'a':  // display annotations
        options.show_annotations_ = true;
        break;
      case 'b':  // build dex_ir
        options.build_dex_ir_ = true;
        break;
      case 'c':  // verify the checksum then exit
        options.checksum_only_ = true;
        break;
      case 'd':  // disassemble Dalvik instructions
        options.disassemble_ = true;
        break;
      case 'e':  // exported items only
        options.exports_only_ = true;
        break;
      case 'f':  // display outer file header
        options.show_file_headers_ = true;
        break;
      case 'h':  // display section headers, i.e. all meta-data
        options.show_section_headers_ = true;
        break;
      case 'i':  // continue even if checksum is bad
        options.ignore_bad_checksum_ = true;
        break;
      case 'l':  // layout
        if (strcmp(optarg, "plain") == 0) {
          options.output_format_ = kOutputPlain;
        } else if (strcmp(optarg, "xml") == 0) {
          options.output_format_ = kOutputXml;
          options.verbose_ = false;
        } else {
          want_usage = true;
        }
        break;
      case 'm':  // output dex files to a memmap
        options.output_to_memmap_ = true;
        break;
      case 'o':  // output file
        options.output_file_name_ = optarg;
        break;
      case 'p':  // profile file
        options.profile_file_name_ = optarg;
        break;
      case 's':  // visualize access pattern
        options.visualize_pattern_ = true;
        options.verbose_ = false;
        break;
      case 'w':  // output dex files directory
        options.output_dex_directory_ = optarg;
        break;
      default:
        want_usage = true;
        break;
    }  // switch
  }  // while

  // Detect early problems.
  if (optind == argc) {
    fprintf(stderr, "%s: no file specified\n", kProgramName);
    want_usage = true;
  }
  if (options.checksum_only_ && options.ignore_bad_checksum_) {
    fprintf(stderr, "Can't specify both -c and -i\n");
    want_usage = true;
  }
  if (want_usage) {
    Usage();
    return 2;
  }

  // Open alternative output file.
  FILE* out_file = stdout;
  if (options.output_file_name_) {
    out_file = fopen(options.output_file_name_, "w");
    if (!out_file) {
      fprintf(stderr, "Can't open %s\n", options.output_file_name_);
      return 1;
    }
  }

  // Open profile file.
  ProfileCompilationInfo* profile_info = nullptr;
  if (options.profile_file_name_) {
    int profile_fd = open(options.profile_file_name_, O_RDONLY);
    if (profile_fd < 0) {
      fprintf(stderr, "Can't open %s\n", options.profile_file_name_);
      return 1;
    }
    profile_info = new ProfileCompilationInfo();
    if (!profile_info->Load(profile_fd)) {
      fprintf(stderr, "Can't read profile info from %s\n", options.profile_file_name_);
      return 1;
    }
  }

  // Create DexLayout instance.
  DexLayout dex_layout(options, profile_info, out_file);

  // Process all files supplied on command line.
  int result = 0;
  while (optind < argc) {
    result |= dex_layout.ProcessFile(argv[optind++]);
  }  // while
  return result != 0;
}

}  // namespace art

int main(int argc, char** argv) {
  return art::DexlayoutDriver(argc, argv);
}
