1 //
2 // Copyright (C) 2022 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #pragma once
17 
18 #include <cstdint>
19 #include <optional>
20 #include <set>
21 #include <string>
22 
23 #include "common/libs/utils/result.h"
24 
25 namespace cuttlefish {
26 
27 class InstanceNumsCalculator {
28  public:
29   InstanceNumsCalculator& FromFlags(const std::vector<std::string>&) &;
30   InstanceNumsCalculator FromFlags(const std::vector<std::string>&) &&;
31 
32   InstanceNumsCalculator& FromGlobalGflags() &;
33   InstanceNumsCalculator FromGlobalGflags() &&;
34 
35   InstanceNumsCalculator& BaseInstanceNum(std::int32_t) &;
36   InstanceNumsCalculator BaseInstanceNum(std::int32_t) &&;
37 
38   InstanceNumsCalculator& NumInstances(std::int32_t) &;
39   InstanceNumsCalculator NumInstances(std::int32_t) &&;
40 
41   InstanceNumsCalculator& InstanceNums(const std::string&) &;
42   InstanceNumsCalculator InstanceNums(const std::string&) &&;
43 
44   // if any element is duplicated, only the first one of them is taken.
45   //   E.g. InstanceNums({1, 2, 3, 2}) == InstanceNums({1, 2, 3})
46   // That is how the code was implemented in Android 14
47   InstanceNumsCalculator& InstanceNums(std::vector<std::int32_t>) &;
48   InstanceNumsCalculator InstanceNums(std::vector<std::int32_t>) &&;
49 
50   /**
51    * Finds set of ids using the flags only.
52    *
53    * Especially, this calculates the base from --instance_nums and
54    * --base_instance_num only
55    *
56    * Processes such as cvd clients may see different user accounts,
57    * CUTTLEFISH_INSTANCE environment variable, etc, than the launcher
58    * effectively sees. This util method is still helpful for that.
59    */
60   Result<std::vector<std::int32_t>> CalculateFromFlags();
61 
62   // Calculates the base from the --instance_nums, --base_instance_num,
63   // CUTTLEFISH_INSTANCE, suffix of the user account, and the default value.
64   // Then, figures out the set if ids.
65   Result<std::vector<std::int32_t>> Calculate();
66 
67  private:
68   template <typename T>
69   void TrySet(T& field, Result<T> result);
70 
71   Result<void> setter_result_;
72   std::optional<std::int32_t> base_instance_num_;
73   std::optional<std::int32_t> num_instances_;
74   std::vector<std::int32_t> instance_nums_;
75 };
76 
77 }  // namespace cuttlefish
78